Почему библиотека буфера протокола c ++ неправильно читает двоичные объекты - PullRequest
1 голос
/ 09 декабря 2011

Я создал двоичный файл, используя программу на С ++, используя буферы протокола. У меня были проблемы с чтением двоичного файла в моей программе на C #, поэтому я решил написать небольшую программу на C ++ для проверки чтения.

Мой файл прото выглядит следующим образом

message TradeMessage {
required double timestamp = 1;
required string ric_code = 2;
required double price = 3;
required int64 size = 4;
required int64 AccumulatedVolume = 5;
} 

При записи в буфер протокола я сначала записываю тип объекта, затем длину объекта и сам объект.

coded_output->WriteLittleEndian32((int) ObjectType_Trade); 
coded_output->WriteLittleEndian32(trade.ByteSize()); 
trade.SerializeToCodedStream(coded_output);

Теперь, когда я пытаюсь прочитать тот же файл в моей программе на С ++, я вижу странное поведение.

Мой код чтения выглядит следующим образом:

coded_input->ReadLittleEndian32(&objtype);
coded_input->ReadLittleEndian32(&objlen);
tMsg.ParseFromCodedStream(coded_input);
cout << "Expected Size = " << objlen << endl;
cout<<" Trade message received for: "<< tMsg.ric_code() << endl;
cout << "TradeMessage Size = " << tMsg.ByteSize() << endl;

В этом случае я получаю следующий вывод

Expected Size = 33
Trade message received for: .CSAP0104
TradeMessage Size = 42

Когда я записываю в файл, я пишу trade.ByteSize () как 33 байта, но когда я читаю тот же объект, объект ByteSize () имеет размер 42 байта, который влияет на остальные данные. Я не уверен, что не так в этом. Пожалуйста, совет.

С уважением, Alok

Ответы [ 2 ]

1 голос
/ 16 декабря 2011

Итак, очевидно, я делал очень глупую ошибку при создании бинарных файлов. Я не открывал файл в двоичном режиме, когда записывал в него данные protobuf, заставляя его добавлять странные символы ascii в середине. Это вызвало проблему при чтении данных с использованием библиотеки protobuf-net. Проблема решена здесь. Не нужно было так долго решать эту проблему.

1 голос
/ 09 декабря 2011

Это предположение, основанное на вышесказанном: когда вы используете ParseFromCodedStream, вы на самом деле не ограничиваете его objlen, который вы нашли ранее;таким образом, если поток содержит больше данных, чем это (т. е. это не конец файла), механизм будет пытаться продолжить чтение в EOF.Вы должны ограничить длину до вашего ожидания.Я не эксперт по C ++, поэтому не могу предложить прямого руководства, но если это был C # (с использованием protobuf-net):

objType = ProtoReader.DirectReadLittleEndianInt32(file);
len = ProtoReader.DirectReadLittleEndianInt32(file);

// assume GetObjectType returns typeof(TradeMessage) for our objType
Type type = GetObjectType(objType);
msg = RuntimeTypeModel.Default.Deserialize(file, null, type, len, null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...