我正在开发一个 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 :
To export functions, the __declspec(dllexport) keyword must appear to the left of the calling-convention keyword, if a keyword is specified.
但是我之前提到的声明并没有起作用。
那么 COM DLL 必须使用 def 文件导出它们的方法吗?
更新1
我用不同的方法名称测试了我的声明,如下所示:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
并且该方法导出成功。所以这些说明符可以一起使用。 Visual C++ 编译器似乎将 STDAPI 和 extern "C"HRESULT __declspec(dllexport) __stdcall 视为不兼容。
最佳答案
我认为出现这个问题是因为 __stdcall 函数(对于 32 位构建)通常用下划线前缀和 @count
后缀修饰。但是,如果该函数也被标记为 __declspec(dllexport)
,则会添加额外的装饰(__imp
,我认为)。
如果您愿意使用带有以下编译指示的 .def 文件(我想我会选择 .def 文件),您或许可以避免使用该编译指示:
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
请注意,对于 x64 构建,您可能必须有条件地编译 pragma,我认为应该是:
#pragma comment( linker, "/export:DllGetClassObject" )
关于c++ - 为什么我不能使用 __declspec(dllexport) 从 COM DLL 导出 DllGetClassObject()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3460533/