今天准备用Protobuf做一些序列化,在这个过程中发现了一些问题
编译错误
下载之后按照说明开始按照,在编译的时候发现编译不过,环境是centos 6.5,错误如下
In file included from ./google/protobuf/any.pb.h:25,
from google/protobuf/any.pb.cc:5:
./google/protobuf/metadata.h: In constructor ‘google::protobuf::internal::InternalMetadataWithArena::InternalMetadataWithArena(google::protobuf::Arena*)’:
./google/protobuf/metadata.h:175: error: class ‘google::protobuf::internal::InternalMetadataWithArena’ does not have any field named ‘InternalMetadataWithArenaBase’
./google/protobuf/metadata.h: In constructor ‘google::protobuf::internal::InternalMetadataWithArenaLite::InternalMetadataWithArenaLite(google::protobuf::Arena*)’:
./google/protobuf/metadata.h:204: error: class ‘google::protobuf::internal::InternalMetadataWithArenaLite’ does not have any field named ‘InternalMetadataWithArenaBase’
make[2]: *** [google/protobuf/any.pb.lo] Error 1
make[2]: Leaving directory /home/protobuf/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory
/home/protobuf'
make: *** [all] Error 2
查了一下google发现是一个bug,在#2559已经修复,https://github.com/google/protobuf/pull/2599/commits/141a1dac6ca572056c6a8b989e41f6ee213f8445
就是改了构造函数,将 InternalMetadataWithArenaBase(arena) {} 改成了 InternalMetadataWithArenaBase<UnknownFieldSet, InternalMetadataWithArena>(arena) {},两个地方175行和204行改一下就好了
examples编译出错
examples]$ make cpp
protoc --cpp_out=. --java_out=. --python_out=. addressbook.proto
pkg-config --cflags protobuf # fails if protobuf is not installed
Package protobuf was not found in the pkg-config search path.
Perhaps you should add the directory containing `protobuf.pc'
to the PKG_CONFIG_PATH environment variable
No package 'protobuf' found
make: *** [add_person_cpp] 错误 1
解决方法
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
向前兼容和向后兼容
message Req
{
required int32 msgid = 1;
required string buf = 2;
required int32 len = 3
}
有A和B两个模块,他们之间通过消息进行通信,比如我们有以上消息Req(A ----> B),刚开始有三个字段,后来增加了一个新的字段 消息类型。我们把增加了 消息类型 的版本成为 成为“新版”;之前的叫“老版”。
所谓的“向后兼容”(backward compatible),也称作向下兼容,就是说,当模块B升级了之后,它能够正确识别模块A发出的老版的协议。由于老版没有“消息类型”,我们可以把“消息类型”属性设置成optional,或者设置一个缺省值。
所谓的“向前兼容”(forward compatible),也称作向上兼容,就是说,当模块A升级了之后,模块B能够正常识别模块A发出的新版的协议。这时候,新增加的“消息类型”会被忽略。