protocol buffer入门
本文档完全参考google protocol buffer编写:https://developers.google.com/protocol-buffers/docs/cpptutorial
1、编译protocol buffer
生成protoc和一些共享库
#安装依赖库 g++依赖个人来定
yum install -y autoconf automake libtool curl make g++ unzip gcc gcc-c++
#安装包https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz
#这个是cpp版本的
tar -zxf protobuf-cpp-3.17.3.tar.gz
cd protobuf-3.17.3/
./autogen.sh
./configure
make && make install
#默认安装在/usr/local/下
2、编写proto
//addressbook.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;
}
message AddressBook {
repeated Person person = 1;
}
3、根据proto生成c++文件
mkdir build
protoc -I./ --cpp_out=./build ./addressbook.proto
#生成的.h和.cc文件在build下
4、编写测试代码
#include <iostream>
#include <string>
#include <fstream>
#include "addressbook.pb.h"
using namespace std;
void PromptForAddress(tutorial::Person *person)
{
cout << "Enter person ID number: ";
int id;
cin >> id;
person->set_id(id);
cin.ignore(256,'\n');
cout << "Enter name: ";
getline(cin, *person->mutable_name());
cout << "Enter email address: ";
string email;
getline(cin,email);
if(!email.empty()){
person->set_email(email);
}
while (true) {
cout << "Enter a phone number (or leave blank to finish): ";
string number;
getline(cin, number);
if (number.empty()) {
break;
}
tutorial::Person::PhoneNumber* phone_number = person->add_phones();
phone_number->set_number(number);
cout << "Is this a mobile, home, or work phone? ";
string type;
getline(cin, type);
if (type == "mobile") {
phone_number->set_type(tutorial::Person::MOBILE);
} else if (type == "home") {
phone_number->set_type(tutorial::Person::HOME);
} else if (type == "work") {
phone_number->set_type(tutorial::Person::WORK);
} else {
cout << "Unknown phone type. Using default." << endl;
}
}
}
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
//这里被我注释掉,是刚开始没有那个文件,执行过一次后就可以放开了
/*{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
} else if (!address_book.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}*/
// Add an address.
PromptForAddress(address_book.add_person());
{
// Write the new address book back to disk.
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
5、编译测试代码
#添加环境变量,否则pkg-config找不到protobuf的
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
###############
[root@jslab build]# pkg-config --cflags --libs protobuf
-pthread -I/usr/local/include -L/usr/local/lib -lprotobuf -lpthread
###############
#编译代码,这里需要加上-std=c++11否则会报错,应为protobuf有很多c++11的新特性
g++ test_seri.cc addressbook.pb.cc -std=c++11 `pkg-config --cflags --libs protobuf`
#生成的a.out不能执行,libprotobuf.so.28 => not found
#############
[root@jslab build]# ldd a.out
linux-vdso.so.1 => (0x00007fff9a978000)
libprotobuf.so.28 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5da1fd3000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f5da1ccb000)
libm.so.6 => /lib64/libm.so.6 (0x00007f5da19c9000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5da17b3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5da13e5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5da21ef000)
#############
#添加路径
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
#执行
./a.out res
#############
[root@jslab build]# touch res
[root@jslab build]# ./a.out res
Enter person ID number: 12
Enter name: hello
Enter email address: helo@word.com
Enter a phone number (or leave blank to finish): 123456
Is this a mobile, home, or work phone? work
Enter a phone number (or leave blank to finish): 234567
Is this a mobile, home, or work phone? mobile
#############
参考:
https://blog.csdn.net/cc1949/article/details/105655377
https://blog.csdn.net/Programmer_H/article/details/8890800