固定大小的结构体数组类型

12

如何在C#中声明结构类型的固定大小数组:

[StructLayout(LayoutKind.Sequential,Pack=1), Serializable]
public unsafe struct MyStruct{
    ...
}

public class MyClass {
    ...
    public fixed MyStruct myStruct[256];
}

如何解决 CS1663 错误:不允许使用固定大小的结构类型缓冲区?由于我需要频繁地将其封送到本机 C++,因此不想使用 C# 或“托管集合数据结构”类型。

2个回答

12

如果您的C#结构仅使用原始数据类型,并且与C++中的本机结构具有完全相同的布局,则可以通过手动内存管理和不安全代码来避开这些限制。作为奖励,您将通过避免封送来提高性能。

分配内存:

IntPtr arr = Marshal.AllocHGlobal (sizeof (MyStruct) * 256);

这基本上就是 malloc,所以分配的内存超出了 GC 的感知范围。

你可以将 IntPtr 传递给本地代码,就像它是一个 MyStruct [256] 一样,只有 IntPtr 会被 marshalled,而不是它指向的内存。本地和托管代码可以直接访问同一块内存。

要使用 C# 指针读写数组中的结构体:

static unsafe MyStruct GetMyStructAtIndex (IntPtr arr, int index)
{
    MyStruct *ptr = ((MyStruct *)arr) + index;
    return *ptr;
}

static unsafe void SetMyStructAtIndex (IntPtr arr, int index, MyStruct value)
{
    MyStruct *ptr = ((MyStruct *)arr) + index;
    *ptr = value;
}

别忘了

Marshal.FreeHGlobal (arr);

当你使用完内存后,需要用free来释放它。


4
你做不到;根据定义

唯一的限制是数组类型必须为boolbytecharshortintlongsbyteushortuintulongfloatdouble


@uray 我唯一能建议的就是使用普通数组。如果不可能的话,那么... - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接