尝试使用IDL创建的COM对象时出现链接器错误

时间:2016-09-29 14:14:49

标签: windows visual-studio-2012 com idl

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

EXTERN_C const CLSID CLSID_COComponent;

#ifdef __cplusplus

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

但是,当我将此标题添加到我的项目中时,尝试在CLSID_COComponent调用中使用CoCreateInstance:。

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时,它会进行编译。

完全相同的代码已用于不同的项目中,我看到它的工作原理。我的问题是,我可能做错了什么?

1 个答案:

答案 0 :(得分:2)

  

完全相同的代码已用于不同的项目中,我看到它的工作原理。我的问题是,我可能做错了什么?

这意味着,代码本身没有任何问题。它必须是代码外部的东西。提示位于CLSID声明中:

EXTERN_C const CLSID CLSID_COComponent;

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

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

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

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