protobuf试用(C++)

书写proto文件

主要根据https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ 文章来操作

关于grpc官方示例的解读:http://doc.oschina.net/grpc?t=57966

试用嘛,就是这么简单:

$more lm.helloworld.proto
syntax = "proto2";
package lm;
message helloworld
{
    required int32 id = 1;
    required string str = 2;
    optional int32 opt=3;
}

这里说一下,第一行指定了proto2,如果不指定,则默认就是proto2,也可以指定成proto3,不过proto3不支持optonal了,用proto3的话protoc编译时那个optional会报错,咱们用proto2吧,反正现在大厂子里那些笨重的代码基本都是用的proto2.

编译proto文件

一般教材上会说需要这么编译:protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto

-I指定proto文件的位置,--cpp_out指定编译结果的放置位置,也就是cc文件和h文件的放置位置。后面就是proto文件本身了。我实际发现只有后面两个是必须的,就是目标位置和源文件。

$protoc --cpp_out=./ lm.helloworld.proto
$ls
lm.helloworld.pb.cc  lm.helloworld.pb.h  lm.helloworld.proto

所以对一个proto文件进行编译其实就是为了得到对应的cc文件和h文件

lm.helloworld.pb.h里面定义了一个class,名字就是helloworld,继承自g家的叫做Message的base类;

protobuf试用(C++)_第1张图片

对应的lm.helloworld.pb.cc当然就是这个helloworld类的实现,粗略看了下,cc文件里面实现的方法大部分较少在业务代码中直接使用,cc里好多方法也主要是为了支撑protobuf运行机制的,除非是高端用户,一般的使用需求就看h就可以了,主要被用户使用的比如set_xxx()都在头文件里inline了。

 使用

写了个简单的不能再简单的使用代码(其实就是开头ibm那篇文章改改),其实就是把一个有值的msg1序列化到文件tst.log中,然后再从tst.log里反序列化到空的msg2里面,最后我们打印一下msg2看各个字段值是否正确。

#include 
#include 
#include "lm.helloworld.pb.h"
using namespace std;

void ListMsg(const lm::helloworld & msg){
    cout << msg.id()<

这里面序列化和反序列化的代码为什么要在不同作用域内呢?

      那是因为input和output虽然都指向同一个文件tst.log,但是如果两者在同一作用域的话,open的时候会导致各自的open是不同的临时文件,直接运行会发现output指向的临时文件里根本没有数据出现“Can't parse message of type "lm.helloworld" because it is missing required fields: id, strfailed to parse”这样的运行错误;

      如果input和output放在不通的作用域,当input的作用域退出时fstram的析构函数自然会close这个文件,然后output再去open的时候就能保证open的是同一文件了。(当然可以把序列化和反序列化分别写在不同的进程里,自然就规避这个问题了)

1. 编译---迫不及待的萌新编译:

g++ *.cpp lm.helloworld.pb.cc -o tst

结果就是一堆ld错误,你得告诉编译器使用lprotobuf啊,原来要这样:

g++ *.cpp lm.helloworld.pb.cc -lprotobuf -o tst

2. 运行---迫不及待的萌新运行,结果:

$./tst
./tst: error while loading shared libraries: libprotobuf.so.15: cannot open shared object file: No such file or directory

没找到protobuf.so啊。没关系,~/.bashrc里加一句

protobuf试用(C++)_第2张图片

当然得保证protobuf的库确实是在/usr/local/lib下面,如果是其他路径,这里bashrc里做对应export。

3.再运行,一切OK

你可能感兴趣的:(杂七杂八)