【问题标题】:How do I declare a embedded struct in C# like a embedded record in delphi?如何在 C# 中声明嵌入式结构,就像在 delphi 中嵌入记录一样?
【发布时间】:2012-02-24 04:29:56
【问题描述】:

我在 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#,所以我需要内存结构是一样的,那么除了写20个像Kernel KernelOne这样的东西外,我应该如何在C#中声明结构; Kernel KernelTwo。。。

【问题讨论】:

    标签: c# delphi struct pinvoke record


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢大卫;像理查德施耐德一样,我今天学到了一些新东西。不过我很好奇:上面的声明导致类型的大小为 80(由 Marshal.SizeOf 报告),但 Kernels 的默认值为 null,并且可以分配任意长度的 Kernel[]。所以托管类型显然是一个普通的托管类型。你知道它是如何编组的(特别是如果托管数组的长度错误)?你知道这是在哪里记录的吗? msdn.microsoft.com/en-us/library/z6cfh6e6(v=vs.100).aspx 没有太多细节。再次感谢!
    • 额外的项目将被截断。缺少的项目将使用默认值进行编组。
    【解决方案2】:

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

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

    编辑

    fixed 的这种用法是在 C# 2.0 中添加的,根据documentation for "fixed size buffers."

    编辑 2

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

    【讨论】:

    • @RichardSchneider 谢谢 :-) 我添加了文档链接,以防您感兴趣。
    • @phoog 谢谢。但是除了不安全的代码,如果不能使用 /unsafe 构建程序集,还有什么“安全”的吗?
    • @RichardSchneider 调查了 David Heffernan 的解决方案,我发现固定大小的缓冲区仅限于某些原始类型。 :(有关详细信息,请参阅编辑后的帖子。
    猜你喜欢
    • 2013-11-20
    • 1970-01-01
    • 2012-05-21
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多