c++使用protobuf3,附例子

2020-12-07  本文已影响0人  blockchain改变世界

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 删除

具体使用下面附一个例子:


Screenshot from 2020-12-07 15-04-00.png
  1. 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;
}
  1. 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;
    }
}
  1. 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 文件的输出路径

  1. 编译
g++ main.cpp game.pb.cc `pkg-config --cflags --libs protobuf` -lpthread

注意: 以上命令的顺序会对编译结果产生影响,链接参数需要放在后面才可以,下面的命令则会报错

# 错误的编译指令!
g++ `pkg-config --cflags --libs protobuf` -lpthread main.cpp game.pb.cc

参考:

  1. http://www.cppblog.com/colorful/archive/2012/05/05/173761.html
  2. https://blog.csdn.net/Design_by_TaoZ/article/details/84960595
  3. https://www.cnblogs.com/DswCnblog/p/6700660.html
上一篇下一篇

猜你喜欢

热点阅读