为什么我不能使用 __declspec(dllexport) 从 COM DLL 导出 DllGetClassObject()?
我正在开发一个 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) 关键字必须出现在 调用约定关键字,如果 指定了关键字。
但我之前提到的声明根本不起作用。
那么 COM DLL 必须使用 def 文件导出其方法吗?
更新1
我用不同的方法名称测试了我的声明,如下所示:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
并且该方法已成功导出。所以这些说明符可以一起使用。 Visual C++ 编译器似乎将 STDAPI 和 extern "C" HRESULT __declspec(dllexport) __stdcall 视为不兼容。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为出现这个问题是因为 __stdcall 函数(对于 32 位版本)通常用下划线前缀和
@count
后缀修饰。但是,如果该函数也被标记为 __declspec(dllexport) 则会添加额外的装饰(我认为是 __imp)。如果您愿意接受该编译指示,您也许可以避免使用带有以下编译指示的 .def 文件(我想我会选择 .def 文件):
请注意,对于 x64 构建,您可能有有条件地编译编译指示,我认为是:
This problem occurs I think because a __stdcall function (for 32-bit builds) is normally decorated with a underscore prefix and an
@count
postfix. But if the function is also marked as__declspec(dllexport)
additional decorations are added (__imp
, I think).You might be able to avoid using a .def file with the following pragma, if you're willing to live with the pragma (I think I'd go for the .def file):
Note that for an x64 build, you might have to conditionally compile the pragma, which I think would be:
它无法编译,因为 objbase.h 中的原始声明没有 __declspec(dllexport) 属性。您不能将其添加到定义中。无论如何都没有帮助,名称装饰不合适。迈克尔向您展示了该怎么做。
It doesn't compile because the original declaration in objbase.h didn't have the __declspec(dllexport) attribute. You cannot add it in the definition. Won't help anyway, the name decoration isn't appropriate. Michael showed you what to do about that.
我会勇敢地说“是”。
甚至 Visual Studio 2008 也会自动为 ATL COM .dll 项目生成 .def 文件。
I'm going to go out on a limb and say yes.
Even Visual Studio 2008 automatically generates the .def file for ATL COM .dll projects.