使用 PInvoke 将点 (x,y,z) 列表从 C 返回到 C#
我需要使用 PInvoke 将 C dll 中的点列表返回到 C# 应用程序。这些是 3 个维度 [x,y,z] 中的点。点数根据型号的不同而不同。在 C 中,我处理这个结构的链接列表。但我不知道如何将其传递给 C#。
在我看来,我必须返回一个灵活的二维数组,可能在一个结构中。
对于如何做到这一点有什么建议吗?关于如何在 C 中返回它以及如何在 C# 中访问它的想法都受到高度赞赏。
I need to return a list of points i have from a C dll to a C# application using PInvoke. These are points in 3 dimensions [x,y,z]. The number of points varies by what kind of model it is. In C i handle this a linked list of structs. But I don't see how i can pass this on to C#.
The way I see it, I have to return a flexible two dimensional array, probably in a struct.
Any suggestions to how this can be done? Both ideas on how to return it in C and how to access it in C# are highly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可以传回结构体的链接列表,但是处理起来会很麻烦,因为您必须编写代码来循环指针,从本机内存读取数据并将其复制到托管内存空间。我会推荐一个简单的结构数组。
如果你有一个像下面这样的 C 结构体(假设 32 位整数)...
...那么你在 C# 中的表示方式几乎相同:
现在要传回一个数组,最简单的方法是让你的本机代码分配数组并将其作为指针传递回来,以及另一个指定元素大小的指针。
您的 C 原型可能如下所示:
P/Invoke 声明将如下所示:
MarshalAs
属性指定应使用第二个参数中指定的大小对数组进行封送处理(您可以阅读有关此内容的更多信息)在 MSDN 上,"默认数组编组”)。如果您使用此方法,请注意您必须使用
CoTaskMemAlloc
分配本机缓冲区,因为这是 .NET 封送拆收器所期望的。否则,您的应用程序将出现内存泄漏和/或其他错误。以下是我在验证答案时编译的简单示例的片段:
然后,托管调用者可以非常简单地处理数据(在本示例中,我将所有互操作代码放在名为
NativeMethods
的静态类中):A linked list of structs could be passed back, but it would be quite a hassle to deal with, as you would have to write code to loop through the pointers, reading and copying the data from native memory into managed memory space. I would recommend a simple array of structs instead.
If you have a C struct like the following (assuming 32-bit ints)...
... then you'd represent it nearly the same way in C#:
Now to pass an array back, it would be easiest to have your native code allocate the array and pass it back as a pointer, along with another pointer specifying the size in elements.
Your C prototype might look like this:
The P/Invoke declaration would then be this:
The
MarshalAs
attribute specifies that the array should be marshaled using the size specified in the second parameter (you can read more about this at MSDN, "Default Marshaling for Arrays").If you use this approach, note that you must use
CoTaskMemAlloc
to allocate the native buffer as this is what the .NET marshaler expects. Otherwise, you will get memory leaks and/or other errors in your application.Here is a snippet from the simple example I compiled while verifying my answer:
The managed caller can then deal with the data very simply (in this example, I put all the interop code inside a static class called
NativeMethods
):