Как использовать COM DLL в моей программе C ++ - PullRequest
7 голосов
/ 04 марта 2010

Я хочу использовать COM DLL в моей библиотеке 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. Так что я знаю, что это признает.

Что я здесь не так делаю?

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

Ответы [ 3 ]

3 голосов
/ 04 марта 2010

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

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

2 голосов
/ 04 марта 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
1 голос
/ 04 марта 2010

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

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

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

Веселись!

...