protobuf学习笔记

Protobuff 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

之前由于要用levelDB存feature,而levelDB的key只能是string(?,反正不能是一个数组), 使用了protobuf. protobuf本身还比较easy,不过目前似乎protobuf2仍然是主流,但是由于最近在看gRPC的缘故,要使用protobuf3. 如果protobuf2没有卸载干净,绝对欲仙欲死…记录一些坑.详细一点的笔记之后补.

// protobuf3坑好多啊…语法全靠猜,也是有毒 

行吧,怪我没找到orz,生成的cpp语法部分在 这里

先放参考资料好了。一开始找到一个pdf文档,说是官方文档的翻译版…但实际上感觉,讲得很烂。直接看官方文档比较好。

其中 Language Guide (proto3) 讲了protobuf3的proto文件的语法相关。

Protocol Buffer Basics: C++ 讲了怎么从编写proto文件到在cpp中使用的一般步骤(注意此处貌似是按照protobuf2讲的)

C++ Generated Code 讲了生成的cpp代码的接口,并且强调了protobuf2和protobuf3的区别。

生成相应代码的语法为: protoc  –cpp_out=.    test.proto

编译选项为:g++ mytest.cc test.pb.cc -o test -lprotobuf

可能遇到这个问题

Undefined reference to google protobuf

解决办法是卸载掉系统自带的protobuf相关(ubuntu14.04默认还都是protbuf2,protobuf3我是从源码自己编译的)
apt-get remove libprotobuf-dev

 

如果X是单个的变量,那么语法为set_X(val)

如果X是repeated类型,语法为add_X(val)

protobuf中message的嵌套:

对于如下的.proto


使用cpp代码访问如下:

需要注意,如果我们想要修改某个class中的另一个class的单个值,需要用mutable_name()方法,而不是name()方法.参考如下例子:

Feature里嵌套了一个Single,我现在想修改某个feature中的sin,代码如下:

但是如果要修改的是某个class中另一个class的repeated的值,则要使用add_name.

参考如下例子:

 

需要注意的是生成的代码的大小写敏感问题

对于生成cpp代码来说,无论.proto文件中的变量名是Abc还是aBc还是ABC,在生成的cpp代码中都是abc…

protobuf的大小写敏感有点坑orz..

 

troubleshooting

试图从3.5降级到3.3时编译helloworld无问题,但是运行时报错

折腾了一下午。。发现其实并不是protobuf的问题。。

用gdb调试发现。。。是grpc的一个动态库中check版本挂掉了。。。

观察grpc。。。发现还是4月20号左右的版本。。。于是删掉了所有之前的grpc在/usr/local/lib下的4月的.so文件。。。

再次运行。。成功了orz….

所以这个问题其实是。。。降级grpc遇到的问题。。。

报错太有误导性了。

 

作者: CrazyKK

ex-ACMer@hust,researcher@sensetime

说点什么

您将是第一位评论人!

提醒
wpDiscuz