2

構造体のシリアル化に「protobuf-net」を使用していますが、空の配列が返されます。

public static byte[] PacketToArray(Packet packet)
{
    IFormatter formatter = new BinaryFormatter();
    MemoryStream stream = new MemoryStream();

    Serializer.Serialize(stream, packet);
    byte[] packetArray = stream.GetBuffer();

    stream.Close();

    return packetArray;
}

packetArray[] は最後の「{byte[0]}」にありますが、データが入っているはずです。「パケット」のデータは次のとおりです。

[ProtoContract]
public struct Packet
{
    [ProtoMember(1)] 
    public int opcode;

    [ProtoMember(2)] 
    public string message;
}

また、テストでは、opcode の値は 0 で、メッセージの場合は null です。問題はどこだ?

4

1 に答える 1

3

また、テストでは、値vor opcodeは0であり、メッセージの場合はnullです。問題はどこだ?

何が問題だと思いますか?0バイトはprotobuf-netにとって完全に合法であり、この場合、シリアル化するのに興味深いものは何もないため、予期されます。外部データを必要とせずに、0とを逆シリアル化できます。nullここでの重要なポイント:同じゼロバイトを逆シリアル化すると、オペコードとメッセージが返されます。仕事は終わりました。Packet0null

複数のメッセージを別々に読み取ることができるように「フレーミング」を処理する場合は、SerializeWithLengthPrefix(およびDeserializeWithLengthPrefix)を使用しますが、ここでは問題ありません。

実際には、コードにバグがあります。

byte[] packetArray = stream.GetBuffer();

GetBuffer()を追跡せずに使用すると、ガベージ(この場合はゼロ)を含む特大のバッキングバッファー.Lengthが取得されます。代わりに使用してください。それで:ToArray()

public static byte[] PacketToArray(Packet packet) {
    using(MemoryStream stream = new MemoryStream()) {
        Serializer.Serialize(stream, packet); // or SerializeWithLengthPrefix
        return stream.ToArray();
    }
}
于 2013-02-06T12:22:13.347 に答える