C#dllimport和#x27;跨平台复制复杂数据类型?

C#dllimport和#x27;跨平台复制复杂数据类型?,c#,.net,c++-cli,native,dllimport,C#,.net,C++ Cli,Native,Dllimport,因此,我正在用C#为C dll编写一个包装器。问题是有几个函数使用复杂的数据类型,例如: ComplexType* CreateComplexType(int a, int b); 有没有一种方法可以声明一个有效的C#类型以便使用dllimport? 如果我使用的是仅限Windows的解决方案,我可能会使用C++/CLI作为本机复杂类型和托管复杂类型之间的过渡 我确实可以访问C dll的源代码,因此是否可以使用不透明类型(例如句柄)?Mono在Windows和Linux中使用p/Invoke方

因此,我正在用C#为C dll编写一个包装器。问题是有几个函数使用复杂的数据类型,例如:

ComplexType* CreateComplexType(int a, int b);
有没有一种方法可以声明一个有效的C#类型以便使用dllimport? 如果我使用的是仅限Windows的解决方案,我可能会使用C++/CLI作为本机复杂类型和托管复杂类型之间的过渡


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

Mono在Windows和Linux中使用p/Invoke方面做得很好。具体来说,请参阅封送处理部分,该部分讨论简单类型与复杂类型。如果你想获得创造性,你可以将你的类型序列化为一些方便的基于字符串的格式,比如JSON或XML,并将其用作封送机制。

这样的函数很难从C程序可靠地调用,当你pinvoke它时,它不会变得更好。问题是内存管理,该结构需要再次销毁。这要求调用程序使用与DLL完全相同的内存分配器。这在C程序中很难得到很好的结果,但您可能很幸运,因为您有DLL的源代码,因此可以重新编译它,并确保每个人都使用相同的共享CRT版本

当然,pinvoke marshaller将调用CoTaskMemFree()来释放该结构。很少有真正的C程序使用CoTaskMemAlloc()来分配结构,因此这在XP上是无声的失败,在Vista及更高版本上是AccessViolationException。现代Windows版本有一个更严格的堆管理器,它不会忽略无效指针

您可以将返回值声明为
IntPtr
,以阻止pinvoke封送员尝试销毁它。然后使用
marshal.PtrToStructure()
手动封送。否则不会阻止内存泄漏,程序最终会因OOM而崩溃。通常无论如何