2012-10-31 48 views
0

我還不是很瞭解COM,和COM somhow谷歌搜索沒有發現在所有的COM(可能是因爲它搜索.COM地址,而不是)。COM,刪除內存而不是調用Release()

我們正在使用視頻捕捉硬件。其SDK允許我們在捕獲幀時註冊回調。對象接口被作爲參數傳遞給該回調過去了,我們可以通過查詢該對象獲取大的緩衝器地址(所捕獲的幀中的像素)和其他信息。現在

,它看起來像調用Release()並不真正刪除存儲,但會降低引用計數,當計數到達0,則將其刪除,對不對?那麼,關於上面提到的那個大緩衝區地址,如何使用「delete」關鍵字「刪除」緩衝區?

看來,我們的節目(不是我寫的,誰寫程序的人退出公司)副本的指針緩衝區爲若干類,但永遠不會調用的任何版本()回調。後來,緩衝區在類中被「刪除」了,似乎Release()幀接口對象也刪除了緩衝區,但它們是一樣的嗎?

COM以某種方式計算引用,但如果用戶代碼只是刪除內存對不起,如果我的問題是晦澀總之,是安全的刪除是從一個COM對象得到一個緩衝

簡化代碼:。可疑情況

void mycallback(IFrame f) 
{ 
    char* buffer; 
    f->GetBuffer(buffer); 
    MyClass m(buffer); 
    ... 
} 

MyClass::DeleteBuffer() 
{ 
    delete m_buffer; 
} 
+0

什麼是IFrame的::的GetBuffer? – Andrey

+0

嘗試搜索「Microsoft組件對象模型」。即使「編程COM + +」提出的結果。當您鍵入「COM」時,您是否期望谷歌閱讀您的想法? – paddy

+0

在一個模塊中分配內存並在另一個模塊中銷燬是一個壞主意。將IFrame :: ReleaseBuffer(char * data)添加到IFrame接口以正確銷燬分配的緩衝區 – pogorskiy

回答

2

當代碼將幀緩衝區內容複製到它自己的緩衝區時,沒有什麼特別的事情發生。幀緩衝區仍然由COM代碼擁有,代碼自己的緩衝區仍然由該代碼擁有。不要刪除COM緩衝區,當COM代碼刪除它也將調用未定義的行爲。如果首先調用AddRef(),則只應在COM接口指針上調用Release()。在這種情況下,AddRef()調用是在調用回調之前由COM代碼創建的。 Release()調用將在回調返回後進行。

眼看回調得到複製的幀是很正常的,在幀緩衝器通常只保持有效回調的持續時間。所以如果你稍後使用它,你必須複製它。

如果你正在追逐內存泄漏,那麼這是不太可能的罪魁禍首。如果幀緩衝區中存在引用計數問題,那麼程序在消耗所有可用內存之前不會持續超過一分鐘。

+0

我們的代碼(不是我寫的)似乎只複製緩衝區的指針,而不是稍後它可能會對它進行memcpy。無論如何,你說的是不使用刪除,但只使用Release(),對不對?好的,我會以此作爲簡短的回答。 –

0

嘗試使用這個地方的operator delete,CoTaskMemFree

+0

在我用C#編寫的測試程序中,我正是用它來釋放緩衝區,而這似乎解決了這個問題。 Marshal.CoTaskMemFree(緩衝液); –

0

與COM接口打交道是:-)

  1. 更棘手確保您匹配的IUnknown ::的AddRef()和IUnknown的::發行()調用
  2. 只要你在相同的上下文中,即使您從COM接口獲取它們,也可以顯式刪除緩衝區。但是確保你在刪除之後使指針無效,這樣就沒有後處理問題。

    MyClass的:: DeleteBuffer() { 如果(m_buffer) { 刪除m_buffer; m_buffer = null; }}