2016-09-29 25 views
0

Я хочу использовать COM-объект в моем проекте VS2012. Для этих целей мне был предоставлен IDL-файл, описывающий объект. Я использовал MIDL для создания файла заголовка, который выглядит (частично), как это:Ошибка компоновщика при попытке использовать COM-объект, созданный с помощью IDL

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

MIDL обычно также создает файл .c, который содержит определение GUID,/iid. Кажется, вы не включили его в свой проект. Использование ключевого слова __uuid действительно простое и полностью действующее обходное решение. –

+1

[Файл UUID интерфейса] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa367283.aspx). Обычно имеет формат * _i.c *. Необходимо скомпилировать и связать с окончательным исполняемым изображением. – IInspectable

+0

Отлично, это действительно трюк! Если вы опубликуете его в качестве ответа, я могу его принять. – Frank

ответ

2

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", так что полное утверждение говорит компилятору, что есть символ называется CLSID_COComponent типа const CLSID, но она определена где-то в другом месте. Не пытайтесь найти это, пусть компоновщик сшит вместе.

Определение для CLSID также генерируется MIDL. Он помещается в Interface UUID File. Имя по умолчанию для этого файла: < idl base > _i.c (может быть переопределено /iid переключателем MIDL). Вы должны включить этот файл в свой проект, чтобы компоновщик нашел символ.

В качестве альтернативы вы можете использовать оператор __uuidof, который не нуждается в файле интерфейса UUID. Я не могу сказать вам, какая магия компилятора делает это. Но если Ханс Пассант называет это "valid workaround", я не стану сомневаться в этом.


Удаление EXTERN_C это позволяет компилировать, по определяющим на символ. Однако во время выполнения он будет терпеть неудачу, поскольку CLSID не сохраняет правильное значение.