如何在C#中声明嵌入式结构,就像在delphi中嵌入式记录一样?

时间:2012-02-24 04:29:56

标签: c# delphi struct pinvoke record

我在delphi中有一个嵌入式记录,如下所示:

TKernel = packed record
    State: Integer;
end;
TKernels = array[0..19] of TKernel;

TShell = packed record
  Kernels: TKernels;
end;

在此,

SizeOf(TShell) = 20 * SizeOf(TKernel).

但如果我使用C#:

struct Shell
{
    Kernel[] Kernels;
    public Shell(int i = 20)
    {
        Kernels = new Kernel[20];
    }
}

然后:     Marshal.SizeOf(Shell)== 4

这意味着内核只是一个指针。 我想用Delphi进行InterOp C#,所以我需要那里的内存结构是一样的,那么我应该如何在C#中声明结构,除了写20个像Kernel KernelOne之类的东西; Kernel KernelTwo ......

2 个答案:

答案 0 :(得分:7)

如果可能的话,我总是会避免不安全,因为不安全的代码是不安全的。在这种情况下很可能避免:

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Kernel
{
    int State;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Shell
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=20)]
    Kernel[] Kernels;
}

答案 1 :(得分:4)

您可以使用fixed关键字在不安全的代码中执行此操作:

unsafe struct Shell
{
    public fixed Kernel Kernels[20];
}

修改

根据documentation for "fixed size buffers."

,在C#2.0中添加了fixed的使用

编辑2

而且,oops,你只能创建一个原始类型的固定大小的缓冲区;正如文档所述,“唯一的限制是数组类型必须是bool,byte,char,short,int,long,sbyte,ushort,uint,ulong,float或double”