结构中的C#数组

想要这样做:(编辑:错误的示例代码,忽略并跳过下面)

struct RECORD { char[] name = new char[16]; int dt1; } struct BLOCK { char[] version = new char[4]; int field1; int field2; RECORD[] records = new RECORD[15]; char[] filler1 = new char[24]; } 

但由于无法在struct中声明数组大小,我该如何重新配置​​?

编辑:布局的原因是我使用BinaryReader读取用C结构编写的文件。 使用BinaryReader和C#struct union(FieldOffset(0)),我想要将头加载为字节数组,然后按照原来的意图读取它。

 [StructLayout(LayoutKind.Sequential)] unsafe struct headerLayout { [FieldOffset(0)] char[] version = new char[4]; int fileOsn; int fileDsn; // and other fields, some with arrays of simple types } [StructLayout(LayoutKind.Explicit)] struct headerUnion // 2048 bytes in header { [FieldOffset(0)] public byte[] headerBytes; // for BinaryReader [FieldOffset(0)] public headerLayout header; // for field recognition } 

我不会首先使用那种模式。 这种内存映射可能适用于c,但不适用于高级语言,如C#。

我只是为我想读的每个成员写一个二进制阅读器的调用。 这意味着您可以使用类并以干净的高级方式编写它们。

它还负责处理endian问题。 而在不同的端系统上使用时,内存映射会中断。

相关问题: 将字节数组转换为托管结构


所以你的代码看起来类似于以下(添加访问修饰符等):

 class Record { char[] name; int dt1; } class Block { char[] version; int field1; int field2; RECORD[] records; char[] filler1; } class MyReader { BinaryReader Reader; Block ReadBlock() { Block block=new Block(); block.version=Reader.ReadChars(4); block.field1=Reader.ReadInt32(); block.field2=Reader.ReadInt32(); block.records=new Record[15]; for(int i=0;i 

使用固定大小的缓冲区

 [StructLayout(LayoutKind.Explicit)] unsafe struct headerUnion // 2048 bytes in header { [FieldOffset(0)] public fixed byte headerBytes[2048]; [FieldOffset(0)] public headerLayout header; } 

Alternativ你可以使用结构并使用以下扩展方法读取它:

 private static T ReadStruct(this BinaryReader reader) where T : struct { Byte[] buffer = new Byte[Marshal.SizeOf(typeof(T))]; reader.Read(buffer, 0, buffer.Length); GCHandle handle = default(GCHandle); try { handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { if (handle.IsAllocated) handle.Free(); } } 

非托管结构可以包含嵌入式arrays。 默认情况下,这些嵌入式数组字段被封送为SAFEARRAY。 在以下示例中,s1是直接在结构本身内分配的嵌入式数组。

 Unmanaged representation struct MyStruct { short s1[128]; } 

数组可以编组为UnmanagedType.ByValArray,它要求您设置MarshalAsAttribute.SizeConst字段。 大小只能设置为常量。 以下代码显示了MyStruct的相应托管定义。 C#VB

 [StructLayout(LayoutKind.Sequential)] public struct MyStruct { [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)] public short[] s1; } 

使用不安全的代码和固定大小的缓冲区可以这样做: http : //msdn.microsoft.com/en-us/library/zycewsya.aspx

固定大小的缓冲区是结构的内联字节。 它们不像char []那样存在于单独的数组中。