c# - 取消/编码包含结构数组的嵌套结构

标签 c# binary marshalling binaryfiles unmarshalling

我希望能够通过 TCP/IP 接收一些由已知结构组成的二进制数据。 我不想与 C 或 C++ 进行互操作,因此适用于这种情况的解决方案对我没有帮助。 不幸的是,另一方无法更改协议(protocol)。 当我尝试读取给定格式的二进制文件时,也会出现问题。

我还检查了 BinaryFormatter 和类似的内容,但他们使用自己的格式,这对我来说是 Not Acceptable 。

这是一组示例结构。我希望能够重建结构的嵌套数组(已知长度)。使用当前代码我得到一个异常:

Could not load type 'NestedStruct' from assembly '...' because it contains an object field at offset 2 that is incorrectly aligned or overlapped by a non-object field.

我希望能够发送/接收(或读/写)struct MainStruct 的实例。

    [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 244, CharSet = CharSet.Ansi)]
    public struct NestedStruct
    {

        [FieldOffset(0)]
        public Int16 someInt;

        [FieldOffset(2), MarshalAs(UnmanagedType.ByValArray, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242

    }

    [StructLayout(LayoutKind.Explicit)]
    public struct OtherNestedStruct
    {
        [FieldOffset(0)]
        public Int16 someInt;
        [FieldOffset(2)]
        public Int16 someOtherInt;

    }


    [StructLayout(LayoutKind.Explicit)]
    public struct MainStruct
    {
        [FieldOffset(0)]
        public double someDouble;
        [FieldOffset(8)]
        public NestedStruct nestedContent;
        [FieldOffset(8 + 244)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13 * 4)]
        public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }

更新:

这是我的最新版本:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct NestedStruct
    {

        public Int16 someInt;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242

    }

    [StructLayout(LayoutKind.Sequential , Pack=1)]
    public struct OtherNestedStruct
    {
        public Int16 someInt;
        public Int16 someOtherInt;

    }


    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct MainStruct
    {

        public double someDouble;

        public NestedStruct nestedContent;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,  SizeConst = 13)]
        public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }

最佳答案

您必须指定 ArraySubType

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct NestedStruct
    {
        public Int16 someInt;
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242
    }

     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct OtherNestedStruct
     {
         public Int16 someInt;
         public Int16 someOtherInt;

     }


     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct MainStruct
     {
         public double someDouble;
         public NestedStruct nestedContent;
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13 * 4)]
         public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }  

    static void Main(string[] args)
    {
        var x = Marshal.SizeOf(typeof(MainStruct));
        //x == 460
    } 

关于c# - 取消/编码包含结构数组的嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14934274/

相关文章:

c++ - 将二进制数转换为十进制数的快速方法

binary - 浮点余弦

c# - 将 vector/数组从非托管 C++ 传递到 C#

go - 如何编码 XML

c# - 如何从 DataTable 返回 Last() 作为 IEnumerable

c# - 如何使用 MVVM Light ViewModelLocator 处理多个 ViewModel

python - Python 中的函数将列表视为全局变量。如何解决这个问题?

java - Lotus Domino C# LtpaToken 类

c# - HttpResponseMessage 返回什么作为 Json

Java POJO 属性的 xml 注释