views:

311

answers:

1

Hi all (and Marc :)

I am using ProtoBuf-Net in my .NET application to serialize the following : (in .proto format)

message ProtoScreenBuffer {
optional int32 MediaId = 1;
optional bytes Data = 2;
optional bool LastBuffer = 3;
optional int64 StartTime = 4;
optional int64 StopTime = 5;
optional int32 Flags = 6;
optional int32 BufferSubType = 7;
optional int32 BufferType = 8;
optional Guid Guid = 9;
repeated int32 EncryptedDataStart = 10;
repeated int32 EncryptedDataLength = 11;
}

My aim is to serialize this and inject it into an ASF file, as a single sample.

I call this to serialize :

MemoryStream ms = new MemoryStream();
Serializer.Serialize<ProtoScreenBuffer>(ms, ProtoScreenBuffer.CreateProtoScreenBuffer (buffer));

then I get a byte array from the ms object :

ms.ToArray();

and I put this byte array in the ASF. The big problem is on my C++ app which reads the ASF sample just fine, I get a memory access violation when I try to deserialize it :(

this is my C++ code :

m_screenBuffer.ParseFromArray(serBuffer, dwInputDataLen); 

(where m_screenBuffer is ProtoScreenBuffer, serBuffer is the raw byte array I got from the ASF file, and dwInputDataLen is the length of it.)

Are any of the things I'm doing here wrong , for what I'm trying to do (serialize in C# .NET and deserialize in C++?)

Thanks alot.

Roey

A: 

Hmm... the only thing in there that I might expect to be messy is the Guid (I recently realised that my encoding of this appears to be fairly crazy-endian). So I think that should work fine, give or take some messy code to decipher the Guid.

To rule out an encoding error, what I would suggest is:

  • serialize the data via C#, to a file (or just look at the bytes on-screen in the debugger)
  • serialize the /same/ data via C++, to a file (or just look at the bytes on-screen in the debugger)

Then:

  • compare the bytes
  • check the length is what you expect (i.e. the number you are passing over)

That should indicate whether it is the encoding, vs something to do with passing the wrong memory address or similar.

Also - check you aren't using GetBuffer() (or at least, if you do use GetBuffer(), make sure you use the .Length from the MemoryStream, and not from the oversized byte[]).

Marc Gravell
Hi Marc, thanks for replying, the GUID is basically : message Guid { optional fixed64 lo = 1; // the first 8 bytes of the guid optional fixed64 hi = 2; // the second 8 bytes of the guid } I will try to compare the two.. thanks
Roey
that came out a bit messy.I meant the GUID is the format you gave me a few days ago, and I will try to compare the C# and C++ version :)Thanks
Roey
Marc, I have compared what I serialize in the .NET application and what I try to deserialize in the C++ app, and they are 100% identical, and I also removed the GUI parameter.It seems the access violation occurs when google protobuffs c++ is trying to decode the "data" field.Would you prefer I start a thread somewhere else to discuss this?
Roey
I'm very glad that the output is identical. That shifts a burden ;-p I think the best place for C++ issues would be here: http://groups.google.com/group/protobuf/topics , and you'll be looking for a reply from Kenton Varda.
Marc Gravell
Can I be 100% sure that the protobuf-net serializes my data correctly?should the "bytes" field have a length at all? or will it serialize any length I give it?
Roey
I don't see a `bytes` field - which `bytes` field do you mean?
Marc Gravell
Re 100% - well, it gave the same answer as C++, so that's a good start...
Marc Gravell
Or is `bytes` the parameter to `ParseFromArray`?
Marc Gravell