Protobuf的简单使用

1、说明

本文主要介绍 Protobuf 库的在C++中的使用方式

平台:ubuntu 18.04

语言:C++

构建工具:cmake

2、Protobuf编译安装

github 下载所需要的 Protobuf 代码,本次下载:protobuf-cpp-3.21.3.tar.gz

解压后编译:

mkdir build && cd build
cmake ..
make -j6
sudo make install
sudo ldconfig

验证安装:

protoc --version #打印版本号
libprotoc 3.21.3

3、cmake中使用

Protobuf 的使用方式很多,可以自行手动生成代码,也可以使用cmake自动生成

3.1、手动生成代码的方式

以下代码的目录结构为:

.
├── CMakeLists.txt
├── include 		#空文件夹,方便存储生成的代码
├── main.cpp
└── message
    └── test.proto

创建 cmake 项目,创建 proto 文件

//文件:test.proto
//这里的package生成代码后,在c++中是命名空间
package test;
message TestOne { //TestOne是类名
	required string name = 1;
	optional int32 age = 2;
}

使用protoc生成代码:

# protoc proto文件 -cpp_out=指定生成的代码路径
# --cpp_out表示生成C++代码,也可以制定多个不同语言
protoc message/test.proto --cpp_out=./include/

以上指令运行之后,则在 include 目录下生成 C++ 代码(.h 和 .cc)

目录结构是:

.
├── CMakeLists.txt
├── include
│   └── message #目录层级和proto相同
│       ├── test.pb.cc #实现文件
│       └── test.pb.h  #头文件
├── main.cpp
└── message
    └── test.proto

项目中使用:

因为代码是手动生成的,所以 CMakeLists.txt 需要像自己写代码一样,把代码加入到项目中,如下:

cmake_minimum_required(VERSION 3.10)
project(protobuf_test)

set(CMAKE_CXX_STANDARD 11)

# 生成的代码中还需要使用到protobuf包
find_package(Protobuf REQUIRED)

include_directories(./include)
include_directories(./include/message)

#生成的的代码需要手动加入
add_executable(protobuf_test 
	main.cpp 
	include/message/test.pb.cc 
	include/message/test.pb.h
)
#因为生成的代码中还用到protobuf,所以还需要链接库
target_link_libraries(protobuf_test
    ${PROTOBUF_LIBRARIES}
)

代码如下:

#include <iostream>
#include <test.pb.h>
using namespace std;
int main()
{
    test::TestOne testOne;
    testOne.set_name("sherlock");
    testOne.set_age(100);

    cout << testOne.name() << endl;
    cout << testOne.age() << endl;
    return 0;
}

编译运行OK

3.2、cmake自动生成代码方式

3.1中使用指令生成代码是最基础的使用,但是一般项目中,大面积的使用,proto文件也会经常删减,自动化集成也不可能运行手动构建,因此支持自动构建是必然

CMakeLists.txt 文件修改如下:

cmake_minimum_required(VERSION 3.10)
project(protobuf_test)

set(CMAKE_CXX_STANDARD 11)
#protobuf包仍然是必须的
find_package(Protobuf REQUIRED)

include_directories(./include)

#主要是这句,使用protoc生成文件
PROTOBUF_GENERATE_CPP(SRCS HDRS message/test.proto)

add_executable(protobuf_test main.cpp ${PROTO_SRCS} ${PROTO_HDRS})

target_include_directories(protobuf_test
    PUBLIC
    ${PROTOBUF_INCLUDE_DIRS}
    ${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(protobuf_test
    ${PROTOBUF_LIBRARIES}
)

PROTOBUF_GENERATE_CPP 宏可以生成代码文件,并返回代码,第一个和第二个参数是传出值,分别表示生成的cpp文件和头文件,第三个参数指定 proto 文件,但是不能指定生成路径,生成的文件在编译根目录下

main.cpp 文件不变,编译运行即可