2012-02-06 130 views
17

我想序列化我的协议缓冲区char *。这可能吗?我知道一个可以序列化到文件按:C++谷歌协议缓冲区:序列化为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; 
} 

但我想序列化到一个C风格的char *跨网络传输。

如何做到这一点?请记住,我对C++很陌生。

回答

34

这很简单:

size_t size = address_book.ByteSizeLong(); 
void *buffer = malloc(size); 
address_book.SerializeToArray(buffer, size); 

检查documentation of MessageLite class也,它的父类的消息,它包含有用的方法。

+0

如何访问此SerializeToArray函数?谢谢, – Eamorr 2012-02-06 10:27:41

+1

int size = address_book.By teSize(); void * buffer = malloc(size); address_book.SerializeToArray(buffer,size); – 2012-02-06 10:50:10

+0

嗨Evgen,有Seri​​alizeToArray被弃用或什么?我正在使用最新版本的协议缓冲区 – Eamorr 2012-02-06 10:51:28

9

您可以将输出端路由至ostringstream,然后使用stream.str()获取字符串,然后使用string.c_str()访问c字符串。

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

string text = stream.str(); 
char* ctext = text.c_str(); 

不要忘了包括sstreamstd::ostringstream

+0

你的传说!非常感谢您提供代码。 – Eamorr 2012-02-06 10:22:39

+3

还有一件事 - 我没有可用的SerializeToOstream函数 - 只是一个SerializeWithCachedSizes(...)和SerializeWithCachedSizesToArray(...);( – Eamorr 2012-02-06 10:26:57

+3

根据Google的protobuf文档,protobuf格式是二进制的,因此可能包含null字节。我曾经在Protobuf序列化的输出中调用c_str()的场合运行一个截断的C字符串,因为空字节被写入到提供的缓冲区,并且进一步使用具有普通C风格函数的那个​​缓冲区来解释它以一个空终止符结束 我不会推荐使用这种方法 - 坦率地说,我不认为将protobufs序列化为C风格的字符串是安全的,这可能是Google不提供此选项的原因 – 2015-05-08 16:33:11

3

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

0

还有一行代码来处理序列化数据可以包含零的事实。

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

string text = stream.str(); 
char* ctext = text.c_str(); // ptr to serialized data buffer 
// strlen(ctext) would wrongly stop at the 1st 0 it encounters. 
int data_len = text.size(); // length of serialized data