1、Protobuf的安装
1.1依赖环境的安装
1 | $sudo apt-get install autoconf automake libtool curl make g++ unzip |
1.2下载 protobuf源码下载
github源代码下载地址:https://github.com/google/protobuf
1 | git clone https://github.com/protocolbuffers/protobuf.git |
1.3 进入目录配置autogen/configure
1 | cd protobuf |
1 2 | ./autogen.sh ./configure --prefix=/usr/local/protobuf |
这个地方如果出现了警告configure: WARNING: no configuration information is in third_party/googletest就需要注意了,这个warning需要解决的,不然后面编译不过
搜索答案发现需要讲googletest下载最新版本 然后放在 thrid/googletest目录下,并且重新命名为googletest(就是删除后面的版本号),tar.gz下载地址:https://github.com/google/googletest/archive/release-1.8.1.tar.gz但是我没有成功,于是尝试一下方法:
如果下载不完整,使用:
1 | git submodule update --init --recursive |
然后再来一遍:
./autogen.sh
./configure --prefix=/usr/local/protobuf
1.4 编译make
1 | make -j4 |
1.5 make check
1 | make check |
如果没有报错 那就是成功了,可以安装了
1.6 安装
1 | sudo make install |
提示:如果安装了两次、最好使用witch查找一下、不然有可能编译的时候各种define找不到
1.7 检测安装是否成功
1 2 | ~$ protoc --version libprotoc 2.6.1 |
2 测试
proto文件的编写方法就是类似于定义一个class / struct(随便怎么理解)存储需要序列化的数据,再把这个数据序列化进行传输,然后反序列化解读出来。
2.1 编写.proto文件
1 2 3 4 5 6 7 8 | message xxx { // 字段规则:required -> 字段只能也必须出现 1 次 // 字段规则:optional -> 字段可出现 0 次或1次 // 字段规则:repeated -> 字段可出现任意多次(包括 0) // 类型:int32、int64、sint32、sint64、string、32-bit .... // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字) 字段规则 类型 名称 = 字段编号; } |
例如:
1 2 3 4 5 6 7 8 | //helloworld.proto package lm; message People { required string str = 1; required int32 id = 2; optional string email = 3; } |
name 是 required修饰,必须出现一次
id 是required修饰,所以必须出现一次
email是optional修饰,可以出现一次或0次
具体使用看看:官方文档C++
2.2 生成proto的读写借口文件
c++为例:生成的对应文件是xxx.pb.cc 和 xxx.pb.h文件
生成命令:
1 2 3 4 5 6 | // $SRC_DIR: .proto 所在的源目录 // --cpp_out: 生成 c++ 代码 // $DST_DIR: 生成代码的目标目录 // xxx.proto: 要针对哪个 proto 文件生成接口代码 protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto |
通过tree来查看目录可以发现结构如下:
1 2 3 4 | . ├── helloworld.pb.cc ├── helloworld.pb.h └── helloworld.proto |
2.3编译链接proto的读写文件
这个时候才是重点,之前在这里卡了很久,主要是安装了两次make install两次protobuf,一次是./configure --prefix=/usr/local/protobuf 另一次 ./cpmfigure 导致有两个protobuf本地库被安装,所以链接的时候出问题了,最后百度了一下删除protobuf了重新来就好了,这里贴一下删除protobuf的方法:
1 2 3 4 5 | sudo apt-get remove libprotobuf-dev which protoc找到文件位置,比如是/usr/local/bin/protoc。 执行sudo rm /usr/local/bin/protoc就可以了。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // main.cpp #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string> #include <pthread.h> #include <fstream> #include "helloworld.pb.h" #define BUFFSIZE 1024 using namespace std; int main() { GOOGLE_PROTOBUF_VERIFY_VERSION; lm::helloworld msg1; msg1.set_id(1); msg1.set_str("test1"); fstream output("./log", ios::out | ios::trunc | ios::binary); if (!msg1.SerializeToOstream(&output)) { cerr << "Failed to write msg." << endl; return -1; } output.close(); cout << msg1.id() << endl; cout << msg1.str() << endl; } |
链接方法:
1 | g++ helloworld.pb.cc main.cpp -lprotobuf -lpthread -std=c++11 |
常见错误:undefined reference to`pthread_once' 。解决方法 不要忘记使用-lpthread
常见错误:error: ‘static_assert’ was not declared in this scope。解决方法 -std=c++11
文件目录如下:
1 2 3 4 5 6 | . ├── a.out ├── helloworld.pb.cc ├── helloworld.pb.h ├── helloworld.proto └── main.cpp |
运行./a.out