2014-06-06 42 views
0

所以我在C#中为C DLL写封装。问题是一些功能使用复杂数据类型例如为:C#dllimport跨平台的复杂数据类型?

ComplexType* CreateComplexType(int a, int b); 

有没有一种方法,我可以宣布一个有效的C#类,这样我可以使用dllimport的? 如果我在做一个纯Windows的解决方案,我可能会使用C++/CLI作为本地复杂类型和托管复杂类型之间的中介。

我确实可以访问C dll的源代码,那么是否可以使用不透明类型(例如句柄)?

回答

0

对于在Windows和Linux中使用P/Invoke,单声道有很好的documentation page。具体来说,请参阅封送处理部分,讨论简单类型和复杂类型。如果你想创造性,你可以将你的类型序列化为一些方便的基于字符串的格式,如JSON或XML,并将其用作编组机制。

1

这样的功能很难从C程序中可靠地调用,但在拼贴时它不会变得更好。问题在于内存管理,那个结构需要被再次销毁。这要求调用程序使用与DLL相同的内存分配器。这在C程序中很少出现,但您可能很幸运拥有DLL的源代码,因此您可以重新编译它并确保每个人都使用相同的共享CRT版本。

当然,C#没有这样的运气,pinvoke编组会调用CoTaskMemFree()来释放结构。很少有真正的C程序使用CoTaskMemAlloc()来分配结构,因此这是XP的无声故障,Vista和更高版本的AccessViolationException。现代Windows版本有一个更严格的堆管理器,不会忽略无效指针。

您可以声明返回值为IntPtr,即停止拼接编组器试图销毁它。然后用Marshal.PtrToStructure()手动编组。这不会阻止内存泄漏,您的程序最终会与OOM崩溃。无论如何。