Формат проводов для буферов протокола не будет таким тривиальным; Я не знаю о том, что можно сделать, но одним из вариантов было бы сериализовать его в буфер с вашим собственным заголовком длины и дополнением при необходимости дополнительными данными.
Вам нужно добавить префикс длины, потому что он не добавлен по умолчанию, иначе это будет чтение мусора в конце вашего буфера. Даже конечные 0 не будут законными (это будет искать номер поля).
Я не могу комментировать версию C ++ или Jon's C #, но для моей версии C # (protobuf-net) вы должны иметь возможность сделать что-то вроде (не проверено):
using(var ms = new MemoryStream(fixedLength)) {
ms.SetLength(fixedLength);
Serializer.SerializeWithLengthPrefix(ms, obj);
if(ms.Length > fixedLength) { /* boom */ }
byte[] arr = ms.ToArray(); // use this
}
Это должно десериализовать нормально, если также используется DeserializeWithLengthPrefix
.
По вопросам (комментариям); SerializeWithLengthPrefix
является protobuf-net -специфичным методом; может быть чем-то в версии C ++, но это довольно просто. Самый простой способ реализовать это с нуля :
- предположим, что мы оставим заголовок фиксированной длины (4 байта), чтобы указать, сколько реальных данных у нас есть
- пропустить 4 байта (или записать 00-00-00-00)
- теперь сериализовать в оставшуюся часть буфера
- найдите сколько байтов вы только что написали
- записать это значение обратно в начало буфера
наоборот, очевидно:
- читать 4 байта и интерпретировать как int
- десериализовать столько, сколько данные
В protobuf-net это немного немного сложнее, поскольку он предлагает еще несколько опций (как должен кодироваться int, и нужно ли оборачивать это так, чтобы весь ) вещь все еще может рассматриваться как поток protobuf со 100% значением - в частности, я подозреваю Я только что описал поведение, если я попросил SerializeWithLengthPrefix
использовать кодирование с фиксированной шириной и "поле 0" ).