2010-02-25 94 views
2

是什麼下面兩行代碼之間的區別:COM對象清理

CComPtr<IInterface> m_interface; 

IInterface* m_interface; 

我知道,但是CComPtr幫助消除內存泄漏,但我得到不一致的結果。當聲明指針爲CComPtr<IInterface> m_interface; 並在我的C#代碼中使用接口時,沒有錯誤,但是在VC++中使用接口時,即使我註釋掉IInterface的實例創建,我也會得到未處理的異常錯誤。

我敢肯定這個問題是在這裏的某個地方:

STDMETHODIMP CSomeClass::get_IClass(IClass** var) 
{ 
     return m_class_var->QueryInterface(var); 
} 
STDMETHODIMP CSomeClass::putref_IClass(IClass* var) 
{ 
    m_class_var = var; 
    return S_OK; 
} 

當我宣佈接口指針有:IInterface* m_interface; 我測試在C#中的接口時得到RPC_E_SERVERFAULT錯誤,必須顯式調用GC。 Collect()避免在實例化幾個對象後引發錯誤。當在VC++中測試接口時,錯誤是一致的,但是當它發生時是不一樣的。如果我註釋掉IInterface的實例創建,代碼運行良好,但是當我嘗試創建一個實例時,我得到和以前一樣的錯誤,只是模糊的未處理的異常錯誤。我在這裏做錯了什麼?

+0

你真的應該花15分鐘製作一個很短的片段,將說明問題。 – sharptooth 2010-02-26 07:56:01

+0

你說「在VC++中使用接口我得到一個未處理的異常錯誤」 - 你可以使用VC++中的接口向我們展示代碼嗎? – 2010-02-26 09:45:26

回答

1

IInstance* m_instance是一個指向IInstance對象的簡單指針。你必須自己管理這個指針的生命週期。你不會像普通對象那樣使用newdelete COM對象。

// instantiate the CoClass which implements IInstance... 
IInstance* instance = 0; 
HRESULT hr = CoCreateInstance(__uuidof(mylibrary::MyCoClass), 0, CLSCTX_INPROC_SERVER, __uuidof(mylib::IInstance), &instance); 

: : 

// We're done, so release the object... 
instance->Release(); 
instance = 0; 

每個COM對象實現引用計數:相反,當你調用WINAPI函數'CoCreateInstance的」操作系統分配的對象。當對對象的最後一個引用已被Release()編輯時,COM對象將自行銷燬。使用CComPtr<>簡化了如何管理COM對象的生命週期。它是一個類似於std :: auto_ptr或Boost的shared_ptr的智能指針,但它可以與COM對象一起工作。通常,在使用CComPtr時,您可以調用CreateInstance成員函數而不是調用WINAPI函數,並且在完成後您不會明確地調用Release。只是讓但是CComPtr走出去的範圍,當它的析構函數被調用,它會調用Release你:

void function() 
{ 
    // instantiate the CoClass which implements IMyInterface... 
    CComPtr<IInstance> instance; 
    instance.CoCreateInstance(__uuidof(mylibrary::MyCoClass)); 

    : : 

    // We're done, so release the object... 
    // dont have to do anything, it will be released when function() exits 
} 
0

CComPtr < IInterface> m_interface是一個對象。而IInterface * m_interface是一個指針。

第一個將在析構函數超出範圍時被調用,我認爲(自從使用它很長一段時間)它會自動調用m_interface - > Release()。

後者是一個指向接口的指針,您必須在調用m_interface-> Release()時進行管理。

您可以確認COM對象在訪問之前沒有被釋放嗎?

+0

謝謝。我已經編輯了一些問題以提供更多信息。我在VC++代碼測試接口實現中調用Release()。它沒有幫助,我懷疑我需要釋放/銷燬非託管代碼內的對象,即使使用CComPtr 但我不確定。 – 2010-02-25 20:13:19

+0

@Reggie:有時候你需要在一個對象上調用AddRef/Release,即使它是由CComPtr管理的。你需要向我們展示VC++代碼,以便我們看看你是否做錯了什麼。 – 2010-02-26 11:06:09

2

CComPtr是一個智能指針,設計用於在COM成語中使用「正確」的東西。

您的get_IClass的代碼看起來不錯,但putref_IClass需要在IClass上調用AddRef,因爲您正在存儲它。如果您使用自動發生的CComPtr

您需要添加更多關於VC++未處理異常的細節。

+0

我已編輯了一些問題以提供更多信息。 – 2010-02-25 20:15:28

+1

謝謝。這有助於更好地理解。我會爲你投票,但我沒有足夠的聲望點 – 2010-02-25 20:39:40