c++ - 为什么我不能使用 __declspec(dllexport) 从 COM DLL 导出 DllGetClassObject()?

标签 c++ com name-decoration

我正在开发一个 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++ 编译器似乎将 STDAPIextern "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/

相关文章:

c++ - map 在什么尺寸下比 vector 更好?

c++ - 在 C++ 中使用 `{}` 聚合初始化 union

c++ - 如何创建 COM DLL(类库)?

c - 如何将 char * 转换为 BSTR?

winapi - 链接到 Windows API 的 PatchAPI

c++ - 修改修饰名 - VS6.0 到 VS2005 迁移

c++ - 如何存储 queue::front 返回的值?

C++ 运算符覆盖来自 2 个类的参数

.net - WiX:同时注册 .NET COM 组件 x86 x64

c - C 中的名称修饰