前言:
Protobuf做为数据交换格式, 被不少人喜欢. 数据压缩比高, 向后兼容性强, 性能优异, 并且对平台中性, 支持多语言(C/C++, JAVA, Python). 优势太多, 实在不胜枚举(居家旅行, 杀人放火必备良药, oh yeah! ^_^).
本篇文章着重记录Linux下对C/C++版Protobuf的编译/连接和API使用.c++
Protobuf下载和安装
让咱们使用protobuf 2.4.1做为样例来展现.
社区url: http://code.google.com/p/protobuf/
下载连接: http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
如下是相关的命令和操做
1). 下载和解压
wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
tar -jxvf protobuf-2.4.1.tar.gz
2). 编译和安装
./configure --disable-shared --prefix=/path/to
make && make install
3). 目录结构
tree -L 2 # 两层的目录结构(bin/inculde/lib), 以下所示:
评注: bin/protoc 是pb生成工具, include, lib则是对应的头文件和相应的静态/动态库app
实战演示
让咱们来编辑一下msg.proto文件工具
message msg_t { required int32 id = 1; }
评注: 简单定义了msg_t类
借助protoc来生成相应语言版本的序列/反序列代码性能
protoc --cpp_out=./ msg.proto
评注: --cpp_out指定了c/c++版本代码的输出路径
最终生成 msg.pb.cc msg.pb.h 两文件
编写以下测试代码:测试
#include "msg.pb.h" #include <stdio.h> #include <assert.h> int main() { char buf[1024] = {'\0'}; int buf_len = 0; msg_t msg1; msg1.set_id(1001); // *) serialize phrase => object to byte array msg1.SerializeToArray(buf, sizeof(buf)); buf_len = msg1.ByteSize(); msg_t msg2; // *) deserialize phrase => byte array to object msg2.ParseFromArray(buf, buf_len); assert(msg1.id() == msg2.id()); return 0; }
进行编译并运行
g++ -o app app.cpp msg.pb.cc -I/path/to/protobuf/include -L/path/to/protobuf/lib -lprotobuf -lpthread
./app
评注: /path/to为具体protobuf的安装目录 ui
连接方式
静态连接仍是动态连接? 这是个问题!
在指定的protobuf库路径中, 若是存在动态链接库, 则编译的程序优先选择动态连接, 不然则采用静态连接的方式.
让咱们用图来对比说明
动态连接方式
在protobuf的lib目录中, 若存在动态链接库(so文件)
则编译后的app可执行程序
使用ldd app分析, 存在以下依赖项
评注: 红线区域标明了引用了动态链接库libprotobuf.so.7
直接执行二进制app文件, 遇到以下错误google
./app: error while loading shared libraries: libprotobuf.so.7: cannot open shared object file: No such file or directory
显然这边须要设定LD_LIBRARY_PATH变量url
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/path/to/protobuf/lib
评注: /path/to/protobuf/lib为实际的protobuf安装路径
静态连接方式
简单的在lib目录移除全部动态链接库(so)文件,
而后进行编译, 使用ldd分析
直接执行app就能够了code
总结:
这边主要讲述了protobuf的编译/安装, 以及小demo编写, 重要的讲述了静态连接和动态连接的区别. 网上资料多以动态连接居多, 但实际上静态连接的方式的须要更直接些.blog