Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何像delphi中的嵌入式记录一样在C中声明嵌入式结构?_C#_Delphi_Struct_Pinvoke_Record - Fatal编程技术网

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

C# 如何像delphi中的嵌入式记录一样在C中声明嵌入式结构?,c#,delphi,struct,pinvoke,record,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

我在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.SizeOfShell==4

这意味着内核只是一个指针。 我想与Delphi互操作C,所以我需要有相同的内存结构,那么除了编写20类内核内核外,我应该如何在C中声明结构;Kernel KernelTwo…

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

编辑

根据

编辑2

而且,面向对象,您只能创建原语类型的固定大小缓冲区;如文档所述,唯一的限制是数组类型必须为bool、byte、char、short、int、long、sbyte、ushort、uint、ulong、float或double。您可以在不安全的代码中使用固定关键字执行此操作:

编辑

根据

编辑2


而且,面向对象,您只能创建原语类型的固定大小缓冲区;正如文档所述,唯一的限制是数组类型必须是bool、byte、char、short、int、long、sbyte、ushort、uint、ulong、float或double,如果可能的话,我会尽量避免不安全,因为不安全的代码是不安全的。在这种情况下,很有可能避免:

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

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

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

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

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

@理查德施奈德谢谢:-我添加了一个文档链接,以防您感兴趣。@phoog谢谢。但是除了不安全的代码,如果程序集不能使用/unsafe生成,还有什么安全的吗?@RichardSchneider调查davidheffernan的解决方案,我发现固定大小的缓冲区仅限于某些基本类型有关详细信息,请参阅编辑后的文章。@RichardSchneider谢谢:-我添加了一个到文档的链接,以防您感兴趣。@phoog谢谢。但是除了不安全的代码,如果程序集不能使用/unsafe生成,还有什么安全的吗?@RichardSchneider调查davidheffernan的解决方案,我发现固定大小的缓冲区仅限于某些基本类型有关详细信息,请参阅编辑后的帖子。谢谢David;像理查德·施耐德一样,我今天学到了一些新东西。不过我很好奇:上面的声明导致Marshal.SizeOf报告的类型大小为80,但是内核的默认值为null,并且可以分配任意长度的内核[]。因此,托管类型显然是正常的托管类型。您知道这是如何封送的吗?特别是当托管数组的长度错误时?你知道这是在哪里记录的吗?目前没有太多细节。再次感谢!额外的项目将被截断。缺少的项目将使用默认值进行编组。谢谢David;像理查德·施耐德一样,我今天学到了一些新东西。不过我很好奇:上面的声明导致Marshal.SizeOf报告的类型大小为80,但是内核的默认值为null,并且可以分配任意长度的内核[]。因此,托管类型显然是正常的托管类型。您知道这是如何封送的吗?特别是当托管数组的长度错误时?你知道这是在哪里记录的吗?目前没有太多细节。再次感谢!额外的项目将被截断。缺少的项将使用默认值进行编组。