protobuf编译器是用c++写的,对于c++用户而言,除了安装protoc之外,还要安装c++运行时。
Please follow the C++ Installation Instructions to install protoc along with the C++ runtime.
或者直接根据以下步骤进行操作:
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
# To build and install the C++ Protocol Buffer runtime and the Protocol Buffer compiler (protoc) execute the following:
./configure
make
sudo make install
sudo ldconfig # refresh shared library cache.
可以解决c++使用protobuf时的绝大部分报错。如果之前安装过protoc,建议卸载之后重新安装。which protoc
找出所有protoc,通过 rm -rf
删除
具体使用下面附一个例子:
- game.proto
syntax = "proto3";
package pt;
message req_login
{
string username = 1;
string password = 2;
}
message obj_user_info
{
string nickname = 1; //昵称
string icon = 2; //头像
int64 coin = 3; //金币
string location = 4; //所属地
}
//游戏数据统计
message obj_user_game_record
{
string time = 1;
int32 kill = 2; //击杀数
int32 dead = 3; //死亡数
int32 assist= 4; //助攻数
}
message rsp_login
{
enum RET {
SUCCESS = 0;
ACCOUNT_NULL = 1; //账号不存在
ACCOUNT_LOCK = 2; //账号锁定
PASSWORD_ERROR = 3; //密码错误
ERROR = 10;
}
int32 ret = 1;
obj_user_info user_info = 2;
repeated obj_user_game_record record = 3;
}
- main.cpp
#include <iostream>
#include <string>
#include "game.pb.h"
int main()
{
pt::rsp_login rsp{};
rsp.set_ret(pt::rsp_login_RET_SUCCESS);
auto user_info = rsp.mutable_user_info();
user_info->set_nickname("dsw");
user_info->set_icon("345DS55GF34D774S");
user_info->set_coin(2000);
user_info->set_location("zh");
for (int i = 0; i < 5; i++) {
auto record = rsp.add_record();
record->set_time("2017/4/13 12:22:11");
record->set_kill(i * 4);
record->set_dead(i * 2);
record->set_assist(i * 5);
}
std::string buff{};
rsp.SerializeToString(&buff);
//------------------解析----------------------
pt::rsp_login rsp2{};
if (!rsp2.ParseFromString(buff)) {
std::cout << "parse error\n";
}
auto temp_user_info = rsp2.user_info();
std::cout << "nickname:" << temp_user_info.nickname() << std::endl;
std::cout << "coin:" << temp_user_info.coin() << std::endl;
for (int m = 0; m < rsp2.record_size(); m++) {
auto temp_record = rsp2.record(m);
std::cout << "time:" << temp_record.time() << " kill:" << temp_record.kill() << " dead:" << temp_record.dead() << " assist:" << temp_record.assist() << std::endl;
}
}
- game.pb.cc 和 game.pb.h
通过命令生成
protoc -I=$SRC_DIR --cpp_out=$OUT_DIR $SRC_DIR/game.proto
中$SRC_DIR
和 $OUT_DIR
都是绝对路径,分别表述 .proto 所在路径以及 .cc 和 .h 文件的输出路径
- 编译
g++ main.cpp game.pb.cc `pkg-config --cflags --libs protobuf` -lpthread
注意: 以上命令的顺序会对编译结果产生影响,链接参数需要放在后面才可以,下面的命令则会报错
# 错误的编译指令!
g++ `pkg-config --cflags --libs protobuf` -lpthread main.cpp game.pb.cc
参考: