我有一个C#应用程序,它通过p / invoke使用第三方(闭源)本机DLL。
在其中一些调用期间,DLL将使用operator new / operator new []分配内存,并返回一个指针,用于读取结果。
在分配和返回后,DLL永远不会释放此内存。如何在C#中执行等效的原生运算符delete / operator delete []?
答案 0 :(得分:6)
不可能。 DLL在内部存储HeapCreate()返回的句柄。你必须知道释放内存的句柄,你无法从DLL中获取它。 和你必须知道DLL的malloc函数分配多少额外字节来调整指针。
如果为DLL编写包装器以便可以调用free(),则甚至无法可靠地执行此操作。 DLL必须使用CRT的DLL版本,你必须使用完全相同版本的编译器和CRT编译包装器,以便它们共享相同的CRT DLL。
如果您真的绝望,您可以尝试破解GetProcessHeaps()。虽然这很难做到,但容易出错,你真的必须知道你在做什么。返回需要释放的指针的DLL即使在C或C ++中也是真正的坏习惯。只是不在.NET中,欢呼垃圾收集器:)
答案 1 :(得分:2)
如果它是全局::operator new
你可以P / Invoke ::operator delete
,虽然你必须使用它的错位名称(当然还有正确的CRT dll)。如果它像AClass *p = new AClass
那样,我不建议尝试使用P / Invoke复制delete p
的效果,要做到正确会有点粗糙(特别是如果他们做了一些有趣的事情)都像重载新/删除)。我建议使用C ++ / CLI来包装一些这些东西,如果它变得毛茸茸(坦率地说,我认为通过P / Invoke调用任何delete
可能是毛茸茸的,值得打破C ++ / CLI来保存你的理智)。
答案 2 :(得分:0)
我不知道如何明确地执行此操作,但您可以将DLL包装在具有此功能的Managed C ++ / CLI包装器中。
答案 3 :(得分:0)
我不知道你是否可以使用非托管代码执行此操作,但单独的应用程序域可能就是答案。将其加载到自己的内存空间中,并在完成后转储整个应用程序域。