c#支持跨平台导入'复杂数据类型

本文关键字:复杂数据类型 导入 支持 跨平台 | 更新日期: 2023-09-27 18:07:36

所以我正在用c#为C dll编写包装器。问题是一些函数使用复杂的数据类型,例如:

ComplexType* CreateComplexType(int a, int b);

是否有一种方法可以声明一个有效的c#类型,以便我可以使用dllimport?如果我在做一个只针对windows的解决方案,我可能会使用c++/CLI作为本地复杂类型和托管复杂类型之间的中介。

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

c#支持跨平台导入'复杂数据类型

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

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

您可以将返回值声明为IntPtr,这样可以阻止pinvoke编组器试图销毁它。然后用Marshal.PtrToStructure()手动编组。这并不能阻止内存泄漏,您的程序最终会因OOM而崩溃。通常无论如何。

Mono有一个很好的关于在Windows和Linux中使用p/Invoke的文档页面。具体来说,请参阅关于封送处理的部分,该部分讨论了简单类型与复杂类型。如果您想发挥创意,可以将类型序列化为一些方便的基于字符串的格式,如JSON或XML,并将其用作封送机制。