使用结构和大小参数索引来编制C#struct



我已经阅读了几个主题,但我仍然无法理解无法轻松将此结构转换为字节数组的真正局限性:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct B {
  public int b_a;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct A {
  public int sizeB;
  [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
  public B[] b;
}

我正在编写一个TCP通信程序,因此我想在结构中构建我的S2C数据包,然后将它们发送为字节[],因此我正在寻找实现此目的的最便宜,最快的方法。

我已经在许多方面尝试了棉花棉花,但是在元帅中总是有一些例外()。

在此示例中,我会收到以下错误:" [...]不能以不受管理的结构进行建议;无法计算有意义的大小或偏移。"

结构初始化例如:

A a = new A();
B[] b = new B[5];
a.sizeB = 5;
a.b = b;
Marshal.SizeOf(a);

您没有像c或c 那样对低级别内存访问的控件。当您在C#中有一个不确定的长度时,您将需要进行一些手动工作。

这是几种实现这一目标的方法。

struct B
{
    public int b_a;
}
struct A
{
    public int sizeB;
    public B[] b;
}

第一个是二进制作者。如果您的结构没有很多字段,则可以更快。

static byte[] ConvertToByte(A a)
{
    using (var ms = new MemoryStream())
    using (var writer = new BinaryWriter(ms))
    {
        writer.Write(a.sizeB);
        foreach (var b in a.b)
            writer.Write(b.b_a);
        return ms.ToArray();
    }
}

另一个像您一样使用编组,但明确地通过数组循环。

static byte[] ConvertToByte(A a)
{
    var bStructSize = Marshal.SizeOf<B>();
    var size = bStructSize * a.b.Length;
    var arr = new byte[size + 4];
    var ptr = Marshal.AllocHGlobal(size);
    for (int i = 0; i < a.b.Length; i++)
        Marshal.StructureToPtr(a.b[i], ptr + i * bStructSize, true);
    Marshal.Copy(ptr, arr, 4, size);
    Array.Copy(BitConverter.GetBytes(a.sizeB), arr, 4);
    return arr;
}

最新更新