【问题标题】:Linker error while trying to use COM object created in with IDL尝试使用通过 IDL 创建的 COM 对象时出现链接器错误
【发布时间】:2017-02-07 22:12:00
【问题描述】:

我想在我的 VS2012 项目中使用 COM 对象。出于这些目的,我得到了一个描述对象的 IDL 文件。我已经使用 MIDL 生成了一个看起来(部分)像这样的头文件:

EXTERN_C const CLSID CLSID_COComponent;

#ifdef __cplusplus

class DECLSPEC_UUID("bla bla bla")
COComponent;
#endif

但是,当我将此标头包含到我的项目中并尝试在 CoCreateInstance 调用中使用 CLSID_COComponent 时:

CComPtr<IModelService> m_IModelService;

hRes = m_IModelService.CoCreateInstance(CLSID_COComponent, NULL, CLSCTX_ALL);

我收到一个链接器错误:

Error   123 error LNK2001: unresolved external symbol _CLSID_COComponent

但是,如果我使用__uuidof(COComponent),它可以正常工作。此外,当从生成的代码中删除 EXTERN_C 时,它会编译。

完全相同的代码已在不同的项目中使用,我已经看到它在其中工作。我的问题是,我做错了什么?

【问题讨论】:

  • MIDL 通常还会生成一个 .c 文件,其中包含 GUID 定义、/iid 命令行选项。似乎您没有将其包含在您的项目中。使用 __uuid 关键字确实是简单且完全有效的解决方法。
  • The Interface UUID File。通常具有 _i.c 格式。需要编译并链接到最终的可执行映像中。
  • 太棒了,确实成功了!如果您将其发布为答案,我可以接受。

标签: windows visual-studio-2012 com idl


【解决方案1】:

在另一个项目中使用了完全相同的代码,我已经看到它在其中工作。我的问题是,我做错了什么?

也就是说,代码本身没有问题。它必须是代码外部的东西。提示在CLSID 声明中:

EXTERN_C const CLSID CLSID_COComponent;

EXTERN_C 扩展为extern "C",所以完整的语句告诉编译器有一个CLSID_COComponent 类型为const CLSID 的符号,但它是在其他地方定义的。不要尝试查找它,稍后让链接器将这些部分拼接在一起。1

CLSID 的定义也是由 MIDL 生成的。它位于Interface UUID File 中。此文件的默认名称是 _i.c(可以用/iid MIDL 开关覆盖)。您必须将该文件包含到您的项目中,以便链接器找到该符号。

或者,您可以使用不需要接口 UUID 文件的 __uuidof 运算符。我不能告诉你,哪个编译器魔法使它起作用。但如果 Hans Passant 称其为 "valid workaround",我不会质疑。


1删除EXTERN_C 允许通过定义符号进行编译。但是,它会在运行时失败,因为 CLSID 没有存储正确的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2022-11-22
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    相关资源
    最近更新 更多