2011-04-14 65 views
1

從C#中用到的第3方COM模塊經由互操作生成的接口泄漏存儲器不正確的互操作簽名造成內存泄漏

的第三方C++方法簽名是:

somemethod(....., long** param3, long** param4) 

所生成的互操作的方法是:

somemethod(...., IntPtr param3, IntPtr param4) 

最後2個PARAMS由umanaged DLL分配陣列,以及從C#Marshal.CoMemFree被釋放(不記得確切SIG大氣壓)

經由COM接口從C++使用相同的方法和在相同的方式釋放不產生泄漏

從命令行使用TLBIMP生產:

TlbImp : warning TI0000 : At least one of the arguments for 
'Sometype.somemethod' cannot be marshaled by the runtime 
marshaler. Such arguments will therefore be passed as a pointer and may 
require unsafe code to manipulate. 

我發現令人驚訝的長** PARAMS可以不會被自動整理。

有更好的瞭解C++的(不包括.com的黑魔法)比.NET,但執行.NET方...

什麼是訪問的正確方法和免費的參數3傳遞迴內存和param4。我懷疑他們應該'out IntPtr'?

回答

0

找到'一種'方法來獲得預期的功能,不知道解決方案有多健全。以下工作不漏

long* arr1 = null; 
long* arr2 = null; 

IntPtr parr1 = new IntPtr(&arr1); 
IntPtr parr2 = new IntPtr(&arr2); 

somemethod(....., parr1, parr2); 

Marshal.CoTaskMemFree(new IntPtr(arr1)); 
Marshal.CoTaskMemFree(new IntPtr(arr2)); 

注意事項:

  1. 沒有試圖訪問數組,我實際上並不需要的內容,但這樣做,我猜大概需要Marshall.Copy調用。直接調用應該是somemethod(.....,ref parr1,ref parr2);然而,看起來IntPtr實際上更像是一個void指針,所以雖然它是通過值傳遞的,但它的值是arr1的地址,因此被調用者可以分配到arr1中,但是它的工作方式是錯誤的,可能arr1或parr1應該被分配給Marshal.CoTaskMemAlloc(?)

  2. 我已經在控制檯應用程序中嘗試過上述操作,但是當指定[STAThread](而不是指定/ default)泄漏停止時,它仍然泄漏。事實上公寓的東西改變了代碼的含義,所以微妙的臭

3

此聲明強烈地與COM自動化不兼容。數組需要作爲SAFEARRAYs傳遞,所以它很清楚它們有多大以及它們的內存是如何管理的。通過一個長的** 通常表明被調用者負責分配數組並返回一個指向數組的指針。正確它應該如何分配是是問題,不清楚它是應該使用進程堆,COM堆還是可以使用CRT堆。

Tlbimp.exe會拋出一個合適的,它不知道如何正確地轉換參數類型。您將不得不用ildasm.exe反編譯interop庫,編輯IL以將參數變爲out IntPtr或out int []並使用ilasm.exe重新編譯。您對分配器的唯一合理猜測是Marshal.AllocCoTaskMem()。可能工作,可能泄漏不好。您需要組件供應商或作者的幫助以避免猜測。

+0

只有粗略瞭解你的anser,它的要點是它看起來不希望。 '被調用者負責分配數組',由第三方和負責釋放的調用者記錄。是否需要使用tlbimp生成的界面?是否可以使用正確的類型手動編寫接口代碼? Alternativley的想法是編寫一個封裝的DLL暴露一個C接口通過PInvoke,不知道多少kludge是... – hanlonj 2011-04-14 13:18:12

+0

'你對分配器唯一合理的猜測是Marshal.AllocCoTaskMem()。可能工作,可能泄漏不好。你需要組件供應商或作者的幫助,以避免猜測。「 - 你是否建議在調用本身在非託管dll中分配實際數組的方法之前,將mem分配給c#端? – hanlonj 2011-04-14 13:26:40

+0

是的,long **表明被調用者必須分配數組。只要你用C#實現代碼,你確實需要互操作庫。你必須編輯它。在C++/CLI中編寫代碼當然是一種選擇,使用#import來導入類型庫並獲取_com_ptr_t智能指針。但是,您仍然不知道如何正確分配陣列。 – 2011-04-15 12:06:06