2015-02-10 209 views
0

我正在寫一個Win32 C++ DLL,它使用在C#中創建的COM對象(B.dll)。 這個DLL(A.dll)提供CMyComObject類,它創建一個COM對象並對其進行訪問。 這是我的代碼。在C++中使用COM對象dll

void CMyComObject::CMyComObject() 
{  
    HRESULT result = CoInitialize(NULL); 
    ... 
    result = CoCreateInstance(CLSID_COMDLL, NULL, CLSCTX_INPROC_SERVER,  IID_COMDLL, reinterpret_cast<void**>(&MyComObject)); 
} 

void CMyComObject::~CMyComObject() 
{ 
    .. 
    CoUninitialize(); 
    .. 
} 

然後,這是一個加載A.dll並訪問COM對象的客戶端程序。 這個程序創建了幾個線程,這些線程同時加載A.dll並創建一個COM對象。

在這種情況下,這是正確的使用CoInitialize()函數還是應該使用CoINITializeEx()函數與COINIT_MULTITHREADED參數? 或者我做了什麼錯誤? (我通過命令「reg_asm.exe B.dll B.tlb/codebase」註冊B.dll)

對不起,我的英語很差。

謝謝。

+0

在這個問題中提供的信息剛好足以給出一個危險*不準確的答案,並且可能*正確的答案。您打算如何訪問這些COM對象以及他們的註冊聲明是什麼(公寓,免費等)也是等式的一部分。而且,fyi CoInit不是一件物品;它的每個線程*。原因和方法太牽涉到這裏的評論。我強烈建議一本關於COM編程的好書/教程,其中有許多*。 – WhozCraig 2015-02-10 05:32:00

回答

1

你應該和之前在該線程上的任何COM活動後使用CoInitialize[Ex]/CoUninitialize,並與具體參數CoInitializeCoInitializeEx之間你的選擇取決於你是否喜歡STA或MTA模式的線程。

說了這麼多,你的初始化:

  1. 不依賴於COM對象本身是否創建的所有線程
  2. 不依賴於應用程序的其他部分可能具有其它COM活動,包括類似的實例相同的COM類
  3. 完全取決於你在所討論線程上的COM活動
  4. 通常不會在類構造函數中發生;通常將COM初始化與頂級線程代碼相關聯,例如在windows消息泵之前或在線程過程的開始時;把它放入構造函數是一種容易碰撞的簡單方法,例如與另一個初始化(尤其是使用不同的公寓模式)或太早的未初始化。

再次總結這一切,你的初始化:

  • 看起來,如果你是使用COM單線程單元模型好啊好啊,你不及格線之間獲得指針
  • 你會更好關閉移動CoInitializeCoUninitialize調出構造函數並將其與線程代碼關聯
  • 請確保檢查返回的值以檢測故障,嘗試在已初始化COM初始化的線程上初始化不匹配的公寓。
  • 您缺少的部分是您必須在呼叫CoUninitialize之前關閉所有COM活動,包括釋放您的MyComObject指針。