C# десериализация неуправляемых двоичных данных с несколькими членами структуры и массивами структур - PullRequest
0 голосов
/ 09 июля 2020

Я уверен, что есть простой ответ, но я застрял. Пытался понять десериализацию неуправляемых структур данных в управляемые данные и для простых структур все в порядке, но возникают проблемы, когда структуры более сложные (структуры с несколькими элементами, массивы структур и т. Д. c)

I пробовал последовательный, автоматический и явный. Автоматические и явные выбросы ошибок, а также последовательная работа, но только для более простых типов.

Ниже мой пример кода. Если я десериализую двоичные данные как PacketHeader, информация верна. Но если я десериализую как BaseDataPacket, это неверно. Даже PacketHeader, хотя это было тогда, когда я делал это сам.

Я бы хотел избежать явного использования, потому что потенциально существует множество различных структур, для которых мне пришлось бы использовать смещения, но я будет, если это единственный способ.

Основная структура

[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BaseDataPacket
{
    public PacketHeader Header;
    public PacketData[] Pdata;
}

Структура заголовка пакета

[Serializable, StructLayout(LayoutKind.Sequential,Pack =1)]
public struct PacketHeader
{
    public ushort Format;
    public byte MajorVersion;
    public byte MinorVersion;
    public byte PacketVersion;
    public PacketType PacketId;
    public ulong SessionUID;
    public float SessionTime;
    public uint FrameIdentifier;
    public sbyte Index;
    public sbyte SecondaryIndex;
}

структура пакетных данных

[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PacketData
{
    public byte d1;
    public byte d2;
    public byte d3;
    public float f1;
    public float f2;
    public float f3;
    public byte b1;
    public float f4;
    public float f5;
}

И вот мой код для маршала

public static T FromBinaryReader<T>(BinaryReader reader)
    {

        // Read in a byte array
        byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));

        // Pin the managed memory while, copy it out the data, then unpin it
        GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        T returnStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return returnStruct;
    }

Есть мысли? Может быть, это повторяющийся вопрос, который я не нашел?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...