一.如何使用Protobuf,首先需要安装
./configure --prefix=/home/work /protobuf/
make && make install
编译成功后将export PATH= /home/work /protobuf/bin:$PATH加入到环境变量中
最后输入 protoc --version命令,如显示libprotoc 2.5.0则安装成功
二. 如何使用ProtoBuf
- 从网上获取安装包 https://github.com/google/protobuf/releases/,可以选择自己的语言种类来安装。
-
#: cd protobuf-xxx 进入目录
-
假如 你希望编译成功后输出的目录 为 /home/work /protobuf/ 则输入如下两条命令:
(1) 定义协议格式 Person.proto
message Person {
required string name=1;
required int32 id=2;
optional string email=3;
enum PhoneType {
MOBILE=0;
HOME=1;
WORK=2;
}
message PhoneNumber {
required string number=1;
optional PhoneType type=2 [default=HOME];
}
repeated PhoneNumber phone=4;
}
.proto文件以包声明开始,防止名字冲突。简单类型:bool, int32, float, double, string.
required: 必须设置它的值
optional: 可以设置,也可以不设置它的值
repeated: 可以认为是动态分配的数组
google工程师认为使用required威害更大, 他们更喜欢使用optional, repeated.
(2) 编译你的协议
运行protoc 来生成c++文件:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/Person.proto
生成的文件为:
Person.pb.h,
Person.pb.cc
3.protobuf API
标准方法
bool IsInitialized() const;// 确认required字段是否被设置
string DebugString() const; // 返回消息的可读表示,用于调试
void CopyFrom(const Person& from); // 使用给定消息值copy
void Clear(); // 清除所有元素为空状态
解析与序列化
bool SerializeToString(string* output) const;// 序列化消息,将存储字节的以string方式输出。注意字节是二进制,而非文本;
bool ParseFromString(const string& data);// 解析给定的string
bool SerializeToOstream(ostream* output) const;// 写消息给定的c++ ostream中
bool ParseFromIstream(istream* input); // 从给定的c++ istream中解析出消息
如果希望向后兼容,必须遵循:
a、不必更改tag数
b、不必添加或删除任何required字段
c、可以删除optional或repeated字段
d、可以添加新的optional或repeated字段,但你必须使用新的tag数。
例子:
void testSimpleMessage()
{
printf("==================This is simple message.================\n");
//序列化LogonReqMessage对象到指定的内存区域。
LogonReqMessage logonReq;
logonReq.set_acctid(20);
logonReq.set_passwd("Hello World");
//提前获取对象序列化所占用的空间并进行一次性分配,从而避免多次分配
//而造成的性能开销。通过该种方式,还可以将序列化后的数据进行加密。
//之后再进行持久化,或是发送到远端。
int length = logonReq.ByteSize();
char* buf = new char[length];
logonReq.SerializeToArray(buf,length); //将 logonReq 对象转化成 buf[]数组
//从内存中读取并反序列化LogonReqMessage对象,同时将结果打印出来。15
LogonReqMessage logonReq2;
logonReq2.ParseFromArray(buf,length); //将char buf[] 数组转化成 logonReq2 对象
printf("acctID = %I64d, password = %s\n",logonReq2.acctid(),logonReq2.passwd().c_str());
delete [] buf;
}
编译时加入 -lprotobuf 库到编译选项中
Java中使用ProtoBuf案例
http://elsila.blog.163.com/blog/static/173197158201402574489/
当使用.proto文件修改后,需要重新生成.xxx.pb.h,和 .xxx.pb.cc文件,然后替换工程中原有的文件,然后修改代码,但最好不要改动 类的名字,否则,改动会很大。
总结
使用ProtoBuf的主要过程:
1.编写proto文件
2.使用命令生成文件
C++:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/Person.proto
Java:
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/Person.proto
3.将生成的文件拷贝的工程目录下
C++会生成 .xxx.pb.h xxxx.pb.cpp两个文件
Java会生成 xxxxx.java 文件
生成的文件中都包含编码和解码的方法,可直接调用,但是需要引用相应的包和库文件。