smw*_*dia 9 c++ com name-decoration
我正在开发一个COM DLL并尝试使用__declspec(dllexport)导出DllGetClassObject()方法.
这里是我的报关表:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
Run Code Online (Sandbox Code Playgroud)
但我一直得到这个错误:
error C2375: 'DllGetClassObject' : redefinition; different linkage
Run Code Online (Sandbox Code Playgroud)
所以我尝试检查所有DllGetClassObject定义的出现.于是在ObjBase.h中找到了以下一个.
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
Run Code Online (Sandbox Code Playgroud)
事实证明,STDAPI是这样的:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
Run Code Online (Sandbox Code Playgroud)
换句话说,它是这样的:
#define STDAPI extern "C" HRESULT __stdcall
Run Code Online (Sandbox Code Playgroud)
根据MSDN:
要导出函数,如果指定了关键字,__ declspec(dllexport)关键字必须出现在calling-convention关键字的左侧.
但我之前提到的声明没有奏效.
我用不同的方法名称测试了我的声明,如下所示:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
Run Code Online (Sandbox Code Playgroud)
并且此方法已成功导出.所以这些说明符可以一起使用.似乎Visual C++编译器将STDAPI和extern"C"HRESULT __declspec(dllexport)__stdcall视为不兼容.
我想这个问题是因为__stdcall函数(对于32位版本)通常用下划线前缀和@count
后缀修饰.但如果该功能也被标记为__declspec(dllexport)
添加了额外的装饰(__imp
我认为).
如果您愿意使用pragma(我想我会选择.def文件),您可以避免使用带有以下编译指示的.def文件:
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Run Code Online (Sandbox Code Playgroud)
请注意,对于x64构建,您可能必须有条件地编译pragma,我认为这将是:
#pragma comment( linker, "/export:DllGetClassObject" )
Run Code Online (Sandbox Code Playgroud)