Как использовать COM dll в моей программе на C++

Я хочу использовать DLL COM в моей библиотеке C++. Как я понял, это #импорт файла .tlb dll, что я и сделал:

#import "mycom.tlb" no_namespace

Проблема в том, что я не совсем знаю, где разместить это объявление. это должно быть внутри файла H или файла CPP? или, может быть, файл stdafx.h? Я попытался поместить его в файл .cpp, просто для тестирования.

в файле H я объявил этот член:

ILogicSecuredPtr m_pbLogic;

(где ILogicSecured — это интерфейс, с которым я хочу работать в своей COM-dll)

Затем я добавил это в конструктор для создания экземпляра интерфейса:

CoInitialize(NULL);
m_pbLogic(__uuidof(LogicSecured)); 

(где LogicSecured — имя объекта, реализующего интерфейс)

В деструктор добавил:

CoUninitialize();

Однако это не скомпилируется, независимо от того, где я пытаюсь разместить объявление #import. он просто не распознает объект ILogicSecured. Я получаю эту ошибку в файле H:

Error   2   error C2146: syntax error : missing ';' before identifier 'm_pbLogic'

Я также должен упомянуть, что когда я нажимаю F12 (в Visual Studio) в объявлении ILogicSecuredPtr, он отлично переносит меня в файл tlh. Так что я знаю, что он признает это.

Что я здесь делаю неправильно?

Большое спасибо. Рой


person Roey    schedule 04.03.2010    source источник


Ответы (3)


Проблема в том, что когда компилятор анализирует файл .h, он еще не видел #import. Поскольку ваш проект небольшой, лучше всего поместить #import в stdafx.h.

Когда вы нажимаете F12, Visual Studio использует информацию базы данных Intellisence, которая формируется путем синтаксического анализа всех источников в порядке, который может отличаться от порядка компиляции. Так что довольно типично, когда Intellisence знает, где что-то объявлено, а компилятор не компилирует это одновременно.

person sharptooth    schedule 04.03.2010
comment
Можно немного усложнить сюжет? Если я попытаюсь добавить #import в файл stdafx.h, то m_pbLogic(__uuidof(LogicSecured)); фрагмент кода не компилируется, говоря об ошибке 18 ошибка C2064: термин не оценивается как функция, принимающая 1 аргумент - person Roey; 04.03.2010
comment
Правильно — вы пытаетесь вызвать конструктор переменной-члена внутри тела конструктора — это не разрешено. Вместо этого вы должны использовать метод CreateInstance() IWhateverPtr. - person sharptooth; 04.03.2010
comment
Спасибо за быстрый ответ. Не могли бы вы предоставить фиктивный пример того, как вызвать CreateInstance в моей ситуации? и где разместить? Спасибо - person Roey; 04.03.2010
comment
вызовите m_pbLogic.CreateInstance( __uuidof(LogicSecured)) вместо того, чтобы пытаться вызвать m_pbLogic(...) - он вернет HRESULT - проверьте его с помощью макроса FAILED() - если вызов не удался, отреагируйте соответствующим образом - выдало исключение или что-то в этом роде. - person sharptooth; 04.03.2010
comment
Спасибо. Еще одна вещь, в моем файле .h я определяю элемент как: ILogicSecuredPtr m_pbLogic; И в файле cpp, где я пытаюсь сделать, как вы сказали, написано, что m_pbLogic не определено, и я также получаю ошибки в файле .h. Могу ли я определить IWhateverPtr как элемент в файле .h?? - person Roey; 04.03.2010
comment
Вы включили заголовок в файл cpp? - person sharptooth; 04.03.2010

Что происходит, если вы импортируете файл dll или tlb, так это то, что препроцессор генерирует файлы tlh и tli. Если tlb стабилен, вы также можете сгенерировать два файла и включить заголовок tlh, как если бы это был обычный заголовок.

Таким образом, ответ помещается в #import там, где вы должны поместить заголовок, потому что он преобразуется во включение файла tlh.

Я использую его следующим образом, чтобы не зависеть от местоположения MSADO15.dll, и добавил файл tlh в свою подрывную деятельность.

#ifndef __ADO__H
#define __ADO__H

#ifdef REBUILD_ADO_HEADER
#import "C:\Programme\Gemeinsame Dateien\system\ado\MSADO15.DLL" rename_namespace("MyAdoNamespace") rename("EOF","EndOfFile")
#else // REBUILD_ADO_HEADER
#include "MSADO15.tlh"
#endif // REBUILD_ADO_HEADER

// Define ADO Namespace as global
using namespace MyAdoNamespace;

#endif // __ADO__H
person Totonga    schedule 04.03.2010

В дополнение к проблемам компиляции, с которыми вы сталкиваетесь, есть и другие проблемы с этим дизайном.

Как правило, библиотеки C++ не должны инициализировать COM в потоках, которые он не создает. Это может вызвать некоторые неприятные, трудно отлаживаемые побочные эффекты. Рассмотрите возможность обновления спецификации интерфейса для вашей библиотеки, чтобы указать, что использование определенных методов или объектов требует инициализации COM. Вы также должны указать требуемую модель потоковой передачи (STA, Free).

Тем не менее, еще одна вещь, на которую вам нужно обратить внимание, это вызов CoUnitialize() до того, как ваш интеллектуальный указатель выйдет за пределы области видимости. Это также может привести к трудным для отладки побочным эффектам. Если вы вызываете CoUnitialize() в деструкторе объекта, содержащего смарт-указатель COM, вам необходимо явно освободить и отсоединить указатель перед вызовом CoUnitialize().

Повеселись!

person BukesRos    schedule 04.03.2010