2010-03-04 47 views
7

我希望在我的C++庫中使用COM DLL。 我想通打算約它的方式,是#IMPORT DLL的.tlb文件,我做到了:如何在我的C++程序中使用COM 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(); 

這不會然而編譯,無論身在何處我試着放置#進口報關。 它只是不識別ILogicSecured對象。 我得到的.h文件這個錯誤:

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

我還要提到的是,當我F12(在Visual Studio)在ILogicSecuredPtr聲明,它帶我到TLH文件就好了。所以我知道它承認它。

我在這裏做錯了什麼?

非常感謝。 Roey

回答

3

問題是,當編譯器解析.h文件時,它還沒有看到#import。既然你的項目很小,你最好的選擇是把#import納入stdafx.h

當您按F12時Visual Studio使用Intellisence數據庫信息,按照順序解析所有源,從而可能與編譯順序不同。因此,Intellisence知道在哪裏聲明瞭某些東西,而編譯器不能同時編譯它,這是非常典型的。

+0

我可以加粗一點情節嗎? 如果我嘗試將#import添加到stdafx.h文件中,則 m_pbLogic(__ uuidof(LogicSecured)); 一段代碼不能編譯,說 錯誤18錯誤C2064:術語不計算爲一個函數帶1個參數 – Roey 2010-03-04 08:11:38

+1

這是正確的 - 您嘗試調用構造函數體內的成員變量構造函數 - 這是不允許的。您應該使用IWhateverPtr的CreateInstance()方法。 – sharptooth 2010-03-04 08:13:00

+0

感謝您的快速回復。 你能提供一個模擬的例子來說明如何在我的情況下調用CreateInstance嗎?以及放置在哪裏? 謝謝 – Roey 2010-03-04 08:51:16

2

如果您導入dll或tlb文件,會發生什麼情況是預處理程序生成tlh和tli文件。 如果tlb是穩定的,你也可以生成兩個文件,幷包含tlh頭,就好像它是一個普通頭。

所以,答案是放在#import的位置,因爲它被轉換爲包含tlh文件。

我以如下方式使用它,使自己獨立於MSADO15.dll的位置,並將tlh文件添加到我的Subversion中。

#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

除了你遇到的編譯問題之外,這個設計還有其他問題。

通常,C++庫不應在未創建的線程上初始化COM。這可能導致一些令人討厭的,難以調試的副作用。考慮更新庫的接口規範,以指示使用某些方法或對象需要初始化COM。您還應該指定所需的線程模型(STA,Free)。

這就是說 - 您需要注意的另一件事是在您的智能指針超出範圍之前調用CoUnitialize()。這也會導致一些難以調試的副作用。如果您在包含COM智能指針的對象的析構函數中調用CoUnitialize(),則需要在調用CoUnitialize()之前顯式釋放並分離指針。

玩得開心!