结构中的C#数组

Rob*_*err 23 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];
}
Run Code Online (Sandbox Code Playgroud)

但由于无法在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
}
Run Code Online (Sandbox Code Playgroud)

Fel*_* K. 22

使用固定大小的缓冲区:

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

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

private static T ReadStruct<T>(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();
    }
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*aos 6

我不会首先使用那种模式.这种内存映射可能适用于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<block.records.Length;i++)
            block.records[i]=ReadRecord();
        block.filler1=Reader.ReadChars(24);
        return block;
    }

    Record ReadRecord()
    {
        ...
    }

    public MyReader(BinaryReader reader)
    {
        Reader=reader;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*nis 6

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

Unmanaged representation
struct MyStruct {
    short s1[128];
}
Run Code Online (Sandbox Code Playgroud)

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

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