C++ Google Protocol Buffers:序列化为char*?

Eam*_*orr 21 c++ protocol-buffers

我想将协议缓冲区序列化为char*.这可能吗?我知道可以按顺序序列化到文件:

fstream output("/home/eamorr/test.bin", ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
  cerr << "Failed to write address book." << endl;
  return -1;
}
Run Code Online (Sandbox Code Playgroud)

但我想序列化为C风格的char*,以便通过网络传输.

这该怎么做?请记住,我对C++很新.

Evg*_*nov 39

这很简单:

size_t size = address_book.ByteSizeLong(); 
void *buffer = malloc(size);
address_book.SerializeToArray(buffer, size);
Run Code Online (Sandbox Code Playgroud)

另外,检查MessageLite类的文档,它是Message的父类,它包含有用的方法.


Fox*_*x32 10

您可以将输出serailze为a ostringstream并使用stream.str()获取字符串,然后使用.来访问c-string string.c_str().

std::ostringstream stream;
address_book.SerializeToOstream(&stream);

string text = stream.str();
char* ctext = text.c_str();
Run Code Online (Sandbox Code Playgroud)

不要忘记,包括sstreamstd::ostringstream.

  • 根据Google的protobuf文档,protobuf格式是二进制格式,因此可以包含空字节.我遇到过在Protobuf序列化输出上调用c_str()导致截断的C字符串的情况,因为空字节被写入提供的缓冲区,并且使用具有普通C风格函数的缓冲区将其解释为结束使用null终止符.我根本不建议使用这种方法 - 坦率地说,我不相信将protobufs序列化为C风格的字符串是安全的,这可能是谷歌不提供此选项的原因. (6认同)
  • 还有一件事 - 我没有Seri​​alizeToOstream函数可用 - 只是一个SerializeWithCachedSizes(...)和SerializeWithCachedSizesToArray(...);( (3认同)

Dav*_*rtz 6

您可以使用ByteSizeLong()来获取消息将占用的字节数,然后SerializeToArray()使用编码的消息填充数组。


Hem*_*lle 5

使用数组的智能指针的解决方案:

size_t size = address_book.ByteSizeLong();
std::unique_ptr<char[]> serialized(new char[size]);
address_book.SerializeToArray(&serialized[0], static_cast<int>(size));
Run Code Online (Sandbox Code Playgroud)