C++ extern "C"的问题

umbrook 2008-09-09 12:12:53
各位好:
我这样用
extern "C"
{
const IID IID_IC;
const CLSID CLSID_Component3;
};

这样用:

extern "C" const IID IID_IC;
extern "C" const CLSID CLSID_Component3;

如果是一般的使用,2者都能编译通过并且能够运行。
但是当我使用了智能指针之后。
VC9.0 报一个错误Compiler Error C2970:
摘自MSDN:
You cannot use the name or address of a static variable as a template argument. The template class expects a const value that can be evaluated at compile time.
意思大概就是说模板需要的是一个常量,而不接收static的变量。
我跟踪代码之后,发现如果是第一种情况的话,
IID_IC的类型就变成了static const IID。

问题:
为什么加了作用域之后IID_IC变成了static类型的。
谁能帮我解疑么?分不多,尽量给。
...全文
180 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2008-09-09
  • 打赏
  • 举报
回复
帮up~
xkyx_cn 2008-09-09
  • 打赏
  • 举报
回复
原因就在于:C++中的const变量默认是内部链接的
xkyx_cn 2008-09-09
  • 打赏
  • 举报
回复
根据我的试验,好像vc里面const全局变量具有static链接属性
下面的代码中如果IID_ICabc前面加上const则会出现Error C2970:

#include <string>
#include <iostream>
#include <sstream>
#include <Guiddef.h>

const int ci = 1;

extern "C" {
IID IID_ICabc;
const CLSID CLSID_Component3;
};

template <const IID* i>
class X {};

using namespace std;

int main( )
{
cout << (void*)&IID_ICabc << endl;
cout << (void*)&ci << endl;
X<&IID_ICabc> x1;

float vf = 1.232f;
stringstream os;
os << vf;

string sf = os.str();

cout << sf << endl;

return 0;
}
xkyx_cn 2008-09-09
  • 打赏
  • 举报
回复
extern "C"是用来修饰函数的,不应用来修饰变量
umbrook 2008-09-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sys0000 的回复:]
贴下你的IPtr的实现。
[/Quote]
#ifndef _IPTR_H_
#define _IPTR_H_
#include <iostream>
#include <assert.h>
#include <objbase.h>
using namespace std;
template <class T, const IID* piid> class IPtr
{
public:
//construction
IPtr()
{m_PI = NULL;}
IPtr(T *ip)
{
m_PI = ip;
if (m_PI != NULL)
{
m_PI->AddRef();
}
}
IPtr(IUnknown *pUnk)
{
m_PI = NULL;
if (pUnk != NULL)
{
pUnk->QueryInterface(*piid,(void **)&m_PI);
}
}
//deconstruction method will call the release()
~IPtr()
{
Release();
}
void Release()
{
if (m_PI != NULL)
{
T *pOld = m_PI;
m_PI = NULL;
pOld->Release();
}
}
//convertion
operator T*()
{
return m_PI;
}
//point operation override.
T& operator*()
{
assert(m_PI != NULL);return *m_PI;
}
T** operator&()
{
assert(m_PI == NULL);return &m_PI;
}
T* operator->()
{
assert(m_PI != NULL); return m_PI;
}
T* operator=(T *ip)
{
if (m_IP != ip)
{
IUnknown *pOld = m_IP;
m_IP = ip;
if (m_IP != NULL)
{
m_IP->AddRef();
}
if (pOld != NULL)
{
pOld->Release();
}
}
return m_pI ;
}
T* operator=(IUnknown *pUnk)
{
IUnknown *pOld = m_IP;
m_IP = NULL;
if (pUnk != NULL)
{
PUnk->QueryInterface(*piid,(void **)&m_PI);
assert(SUCCEEDED(hr) && (m_PI!=NULL));
}
if (pOld != NULL)
{
pOld->Release();
}
return m_IP;
}
//Bool judgement;
BOOL operator!()
{
return (m_PI == NULL)? true: false;
}
operator BOOL() const
{
return (m_PI != NULL)? true: false;
}
const IID& iid()
{
return *piid;
}
private:
T *m_PI;
};
#endif
sxcong 2008-09-09
  • 打赏
  • 举报
回复
没用过VC9
VC6是怎么报的
sys0000 2008-09-09
  • 打赏
  • 举报
回复
贴下你的IPtr的实现。
umbrook 2008-09-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xkyx_cn 的回复:]
贴点代码看看
[/Quote]
//
//_IFace_H_
//
#ifndef _IFACE_H_
#define _IFACE_H_
#include <iostream>
#include <objbase.h>
using namespace std;
interface Ic:IUnknown
{
virtual void __stdcall Fc() = 0;
};
//用法1,当一般的用法的时候,
//查询接口时候等同于用法2,并且都能运行和编译。
//
extern "C"
{
const IID IID_IC;
const CLSID CLSID_Component3;
};
//用法2
//extern "C" const IID IID_IC;
//extern "C" const IID CLSID_Component3;
//
#endif

//
//cpp
//

#include <iostream>
#include <objbase.h>
#include "IPtr.h"
#include "IFace.h"
int main()
{
CoInitialize(NULL);
IPtr<Ic,&IID_IC> spIC;//出错地方
HRESULT hr = ::CoCreateInstance(CLSID_Component3,NULL,CLSCTX_INPROC_SERVER,spIC.iid(),(void **)&spIC);
if (SUCCEEDED(hr))
{
spIC->Fc();
}
else
{
cout << "error" << endl;
}
CoUninitialize();
return 0;
}

//
//Note:
//用法1的时候编译出错:vc9.0提示:
//an expression involving objects with internal linkage cannot be used as a non-type argument
//查msdn:You cannot use the name or address of a static variable as a template argument. The template class expects a const value that can be evaluated at compile time.
// 从中得知模板需要常量而不接收static.跟踪代码,发现如果使用用法1,IID_IC已经变成了static const IID的类型了。
//使用用法2,编译通过。
//question:
//为什么使用extern "C"{....}里面的变量会变成static? ,这个在什么什么发生变化的。为什么使用模板会出错,而一般的使用用法1和用法2都能使用?区别在哪里?
e_sharp 2008-09-09
  • 打赏
  • 举报
回复
UP
xkyx_cn 2008-09-09
  • 打赏
  • 举报
回复
贴点代码看看

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧