我正在开发一个COM dll并尝试使用 __ declspec(dllexport)导出DllGetClassObject()方法。
这是我的声明:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
但我一直收到这个错误:
error C2375: 'DllGetClassObject' : redefinition; different linkage
所以我尝试检查所有DllGetClassObject定义的出现。因此在 ObjBase.h 中找到了以下内容。
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
STDAPI原来是这样的:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
换句话说,就像这样:
#define STDAPI extern "C" HRESULT __stdcall
根据MSDN:
要导出功能, __declspec(dllexport)关键字必须出现在左侧 calling-convention关键字,如果是 指定了关键字。
但我之前提到的声明不起作用。
我使用不同的方法名称测试了我的声明,如下所示:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
此方法已成功导出。所以这些说明符可以一起使用。似乎Visual C ++编译器将 STDAPI 和 extern“C”HRESULT __declspec(dllexport)__stdcall 视为不兼容。
答案 0 :(得分:9)
我认为会出现此问题,因为__stdcall函数(对于32位版本)通常使用下划线前缀和@count
后缀进行修饰。但是如果该函数也标记为__declspec(dllexport)
,我会添加其他装饰(__imp
)。
如果您愿意使用pragma(我想我会选择.def文件),您可以避免使用带有以下编译指示的.def文件:
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
请注意,对于x64构建,您可能必须有条件地编译pragma,我认为这将是:
#pragma comment( linker, "/export:DllGetClassObject" )
答案 1 :(得分:3)
它不能编译,因为objbase.h中的原始声明没有__declspec(dllexport)属性。您无法在定义中添加它。无论如何都不会帮助,装饰名称不合适。迈克尔告诉你该怎么做。
答案 2 :(得分:0)
我要走出去,说是的。
甚至Visual Studio 2008也会自动为ATL COM .dll项目生成.def文件。