尝试使用在 IDL 中创建的 COM object 时出现链接器错误

Linker error while trying to use COM object created in with IDL

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

EXTERN_C const CLSID CLSID_COComponent;

#ifdef __cplusplus

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

但是,当我将此 header 包含到我的项目中,并尝试在 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 时,它会编译。

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

The exact same code has been used in a different project, where I have seen it work. My question is, what could I be doing wrong?

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

EXTERN_C const CLSID CLSID_COComponent;

EXTERN_C 扩展为 extern "C",所以完整的语句告诉编译器有一个类型为 const CLSID 的名为 CLSID_COComponent 的符号,但它在某处定义别的。不要试图查找它,让链接器稍后将这些片段拼接在一起。1

CLSID 的定义也是由 MIDL 生成的。它位于 Interface UUID File. The default name for this file is <idl base name>_i.c (can be overridden with the /iid MIDL 开关中)。您必须将该文件包含到您的项目中,这样链接器才能找到该符号。

或者,您可以使用 __uuidof operator, that doesn't need the Interface UUID File. I cannot tell you, which compiler magic makes this works. But if Hans Passant calls it a ,我不会质疑这一点。


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