从非托管代码返回分配给托管代码的值

本文关键字:托管代码 分配 非托管代码 返回 | 更新日期: 2023-09-27 18:06:02

我想做以下事情:调用unmanaged方法,返回它分配的MyStruct[]类型的数组。

c代码示例:

MyStruct[] foo(int size)
{
   Mystruct* st = (MyStruct*)malloc(size * sizeof(MyStruct));
   return st;
}

如何实现c#调用方法?

谢谢!

从非托管代码返回分配给托管代码的值

System.Runtime.InteropServices名称空间中的Marshal类有许多方法可以帮助您将数据封送到非托管代码中或从非托管代码中封送数据。

你需要声明你的原生方法:

[DllImport("myclib.dll")]
public static extern IntPtr Foo(Int32 size);

以及您的C结构体作为托管值类型(您可以在字段上使用属性来控制它们在封送时如何映射到本机内存):

[StructLayout(LayoutKind.Sequential)]
struct MyStruct {
  public Char Character;
  public Int32 Number;
}

然后你可以使用Marshal.PtrToStructure来封送数组的每个元素到一个托管值:

var n = 12;
var pointer = Foo(n);
var array = new MyStruct[n];
var structSize = Marshal.SizeOf(typeof(MyStruct));
for (var i = 0; i < n; ++i) {
  array[i] = (MyStruct) Marshal.PtrToStructure(pointer, typeof(MyStruct));
  pointer += structSize;
}

注意,您正在使用malloc来分配C代码中的内存。c#无法释放这些内存,你必须提供另一种方法来释放分配的内存。

这应该对您有所帮助http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx

参考这个线程,它有一些关于如何将动态分配的结构体从c++返回到c#作为数组的信息。