從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'?
只有粗略瞭解你的anser,它的要點是它看起來不希望。 '被調用者負責分配數組',由第三方和負責釋放的調用者記錄。是否需要使用tlbimp生成的界面?是否可以使用正確的類型手動編寫接口代碼? Alternativley的想法是編寫一個封裝的DLL暴露一個C接口通過PInvoke,不知道多少kludge是... – hanlonj 2011-04-14 13:18:12
'你對分配器唯一合理的猜測是Marshal.AllocCoTaskMem()。可能工作,可能泄漏不好。你需要組件供應商或作者的幫助,以避免猜測。「 - 你是否建議在調用本身在非託管dll中分配實際數組的方法之前,將mem分配給c#端? – hanlonj 2011-04-14 13:26:40
是的,long **表明被調用者必須分配數組。只要你用C#實現代碼,你確實需要互操作庫。你必須編輯它。在C++/CLI中編寫代碼當然是一種選擇,使用#import來導入類型庫並獲取_com_ptr_t智能指針。但是,您仍然不知道如何正確分配陣列。 – 2011-04-15 12:06:06