protobuf是谷歌的开源序列化协议框架,结构类似于XML,JSON这种,显著的特点是二进制的,效率高,主要用于通信协议和数据存储等方面,算是一种结构化数据的表示方法。
直白点就是通信过程中点数据传输的一种数据结构,阿三的程序要发信息给大头的程序,就可以通过protobuf定义的message传输。
sudo apt-get install autoconf automake libtool curl make g++ unzip
git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure --prefix=/usr
make
//可不检查,没影响
make check
sudo make install
sudo ldconfig # refresh shared library cache.
于是通过技术手段下载了protobuf 2.4.1版本。protobuf 2.x和3.x差异很大,注意版本,有点像python。
By default, the package will be installed to /usr/local. However,
on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH.
You can add it, but it may be easier to just install to /usr
instead.
Google Test not present, Fetching gtest-1.5.0 from web ...
需要gtest,gtest需要连接github,但是连不上。
网上查找了一番,需要修改一下autogen.sh代码。
# Check that gtest is present. Usually it is already there since the
# directory is set up as an SVN external.
if test ! -e gtest; then
pwd
echo "Google Test not present. Fetching gtest-1.5.0 from the web..."
# wget https://github.com/google/googletest/archive/release-1.5.0.tar.gz
# tar xzvf release-1.5.0.tar.gz #发现下载的文件没有后缀名,所以我改成tar xzvf release-1.5.0
mv googletest-release-1.5.0 gtest
fi
6-7行是网友推荐的方法,但是也要连接github,无奈电脑连不上啊。
所以手动下载googletest-release-1.5.0.tar.gz
,解压放入protobuf源码文件路径:/opt/protobuf-2.4.1
然后再次执行即可。
于是定位到文件
src/google/protobuf/compiler/command_line_interface.cc
proto_path_.push_back(make_pair(virtual_path, disk_path));
// 查看proto_path定义:
vector > proto_path_; // Search path for proto files.
索性修改为pair
proto_path_.push_back(pair(virtual_path, disk_path));
终于成功了。
sudo ldconfig
protoc --version //版本号,输出即可
protobuf会根据.proto文件自动生成所需要的C++ .h和.cpp文件,文件内包含必要的调用和赋值函数。
举个例子:
原始.proto文件如下:
syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
生成的API如下:
// name
inline bool has_name() const;
inline void clear_name();
inline const ::std::string& name() const;
inline void set_name(const ::std::string& value);
inline void set_name(const char* value);
inline ::std::string* mutable_name();
// id
inline bool has_id() const;
inline void clear_id();
inline int32_t id() const;
inline void set_id(int32_t value);
// email
inline bool has_email() const;
inline void clear_email();
inline const ::std::string& email() const;
inline void set_email(const ::std::string& value);
inline void set_email(const char* value);
inline ::std::string* mutable_email();
// phones
inline int phones_size() const;
inline void clear_phones();
inline const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phones() const;
inline ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phones();
inline const ::tutorial::Person_PhoneNumber& phones(int index) const;
inline ::tutorial::Person_PhoneNumber* mutable_phones(int index);
inline ::tutorial::Person_PhoneNumber* add_phones();
每个协议缓冲区类都具有使用协议缓冲区二进制格式写入和读取所选类型的消息的方法。这些包括:
bool SerializeToString(string* output) const;
:序列化消息并将字节存储在给定的字符串中。注意,字节是二进制的,而不是文本;只用类作为方便的容器:stringbool ParseFromString(const string& data);
:解析给定字符串中的消息。bool SerializeToOstream(ostream* output) const;
:将消息写入给定C++。ostreambool ParseFromIstream(istream* input);
:解析来自给定C++的消息。istream