错误的互操作签名导致内存泄漏

| 通过互操作生成的接口从C#使用的第三方com模块正在泄漏内存 第三方c ++方法签名为:
somemethod(....., long** param3, long** param4)
生成的互操作方法为:
somemethod(...., IntPtr param3, IntPtr param4)
最后2个参数由umanaged dll分配了数组,并从c#Marshal.CoMemFree中释放(不记得确切的sig atm) 通过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.
我发现令人惊讶的是,**无法自动编组长参数。 比.net更好地了解c ++(不包括Com黑色魔术),但要实现.net方面... 什么是访问和释放在param3和param4中传递回的内存的正确方法。我怀疑它们应该是“ out IntPtr”吗?     
已邀请:
此声明与COM Automation强烈不兼容。数组需要作为SAFEARRAY传递,因此非常清楚它们的大小以及如何管理它们的内存。传递long **通常表示被调用方负责分配数组并返回指向数组的指针。究竟应该如何分配才是问题所在,目前尚不清楚它应该使用进程堆,COM堆还是可以使用CRT堆。 Tlbimp.exe抛出异常,它不知道如何正确转换参数类型。您将必须使用ildasm.exe反编译互操作库,编辑IL以将参数转换为IntPtr或int [],然后再次使用ilasm.exe进行编译。您对分配器的唯一合理猜测是Marshal.AllocCoTaskMem()。可能会工作,可能会严重泄漏。您需要组件供应商或作者的帮助,以避免猜测。     
找到获得预期功能的“一种”方法,不确定解决方案的声音如何。跟随作品而不泄漏
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));
注意事项: 没有尝试访问数组,我实际上不需要内容,但是我想可能需要Marshall.Copy调用。 直观上,调用应该是某种方法(.....,ref parr1,ref parr2);但是看起来IntPtr实际上更像是一个空指针,因此,尽管它通过值传递,但它的值是arr1的地址,因此被调用者可以将其分配给arr1,闻起来有问题,但可能起作用,arr1或parr1应该分配给Marshal.CoTaskMemAlloc(?) 我之前曾在控制台应用程序中尝试过上述操作,但仍会泄漏,但是当指定[STAThread](而不是未指定/默认值)时,泄漏会停止。事实是公寓的事情改变了代码的含义,所以细微的臭味     

要回复问题请先登录注册