2017-06-28 4 views
1

マイいるProtobufメッセージは、私がいるProtobufシリアライゼーション長さが異なる

test.set_input(2.3456); 
test.set_output(5.4321); 
test.set_info(5.0); 

シリアル化されたメッセージは

00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |[email protected]"lx.| 
00000010 15 40 19           |[email protected]| 
00000013 
のように見えるこれらの値を設定すると3倍

syntax = "proto3"; 

message TestMessage{ 
    double input = 1; 
    double output = 2; 
    double info = 3; 
} 

で構成されていtest.serializeToArrayを使用している場合は

であり、goプログラムで正常にデシリアライズできませんでした同じprotobufメッセージを使用します。 C++プログラムからそれを読み取ろうとすると、私は情報として0を受け取るので、メッセージは壊れているようです。

test.serializeToOstreamを使用している場合、私はこのメッセージを受け取りました。これは、goとC++プログラムの両方で正常に逆シリアル化できます。

00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |[email protected]"lx.| 
00000010 15 40 19 00 00 00 00 00 00 14 40    |[email protected]@| 
0000001b 

test.set_input(2.3456); 
test.set_output(5.4321); 
test.set_info(5.5678); 

にシリアル化されたメッセージは、

00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |[email protected]"lx.| 
00000010 15 40 19 da ac fa 5c 6d 45 16 40     |[email protected]\[email protected]| 
0000001b 

に成功し、私の行くとcppのプログラムで読み取ることができようtest.serializeToArraytest.serializeToOstream表情によって生成さの両方を値を設定します。

私はここで何が欠けていますか?最初のケースでserializeToArrayが機能しないのはなぜですか?

編集: 明らかに、serializeToStringもうまくいきます。

ここ

私は比較のために使用されるコード:予想通り

file_a.open(FILEPATH_A); 
file_b.open(FILEPATH_B); 

test.set_input(2.3456); 
test.set_output(5.4321); 
test.set_info(5.0); 

//serializeToArray 
int size = test.ByteSize(); 
char *buffer = (char*) malloc(size); 
test.SerializeToArray(buffer, size); 
file_a << buffer; 

//serializeToString 
std::string buf; 
test.SerializeToString(&buf); 
file_b << buf; 

file_a.close(); 
file_b.close(); 

なぜserializeToArrayが動作しませんの?

EDIT2:

代わりfile_b << buf.data()file_b << buf.data()を使用して、データが破損しているだけでなく、なぜます?

+0

あなたはゴーで同じ長さを持っていますが、長さが違うと何を使用していますか? – Adrian

+0

私はcppのように同じ操作を行うと、長さが異なるcppシリアル化とは対照的に、両方のシリアル化されたメッセージの長さが同じになる – jonadev95

+0

ええ、最初のバージョンは間違ったIMOです。それは27バイトでなければなりません。このヘックスをhttps://protogen.marcgravell.com/decodeに置くと、27バイトのバージョンで同じ番号が出てくるのを確認することができます –

答えて

2

あなたが作っているエラーは、バイナリを文字データとして扱い、文字データAPIを使用していると思います。これらのAPIの多くはであり、最初のゼロバイト(0)ではが停止しますが、これはprotobufバイナリではまったく有効な値です。

基本的にこのようなAPIを使用しないようにする必要があります。バイナリセーフAPIだけに固執する必要があります。

sizeが27であることを示しているので、これはすべて適合します。

基本的に、5.0のバイナリ表現には0バイトが含まれていますが、他の値についても同様の問題が発生している可能性があります。

+0

char配列を渡し、最初のnilバイトの後にostreamが書き込みを終了するので、問題は' file_b << buffer'です。ヌル終了文字列を期待していますか? – jonadev95

+1

@ jonadev95はい、まさにその –

関連する問題