首页 > 其他分享 >【3rd Party】Cpp 中使用 Protobuf

【3rd Party】Cpp 中使用 Protobuf

时间:2023-09-08 13:33:35浏览次数:50  
标签:set Protobuf proto Person person Cpp Party include protobuf

前置条件:

ProtoBuf 的定义和描述

Protocol Buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

怎么感觉到处都在对比 XML 的速度慢啊...

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

使用 ProtoBuf教程:

对 ProtoBuf 的基本概念有了一定了解之后,我们来看看具体该如何使用 ProtoBuf。

第一步,创建 .proto 文件,定义数据结构,如下所示:

//person.proto
package test;

message Person {
	required string name = 1;
	required int32 id = 2;
	required string email=3;
}

我们在上例中定义了一个名为 Person的消息,语法很简单,message 关键字后跟上消息名称。之后我们在其中定义了 message 具有的字段,形式为:

message xxx {
  // 字段规则:required -> 字段只能也必须出现 1 次
  // 字段规则:optional -> 字段可出现 0 次或1次
  // 字段规则:repeated -> 字段可出现任意多次(包括 0)
  // 类型:int32、int64、sint32、sint64、string、32-bit ....
  // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)
  字段规则 类型 名称 = 字段编号;
}

第二步,protoc 编译 .proto 文件生成读写接口:

.proto 文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。ProtoBuf 提供相应的接口代码,可以通过 protoc 这个编译器来生成相应的接口代码,命令如下:

// $SRC_DIR: .proto 所在的源目录
// --cpp_out: 生成 c++ 代码
// $DST_DIR: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码
 
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto
 
protoc ./person.proto --cpp_out=./

生成的.h,.cpp文件为person.pb.h,person.pb.cpp,且.h的定义与proto文件的内容相关联:

namespace test { // 对应 package test;
 
class Person : public ::google::protobuf::Message { //对应 message Person 且继承自::google::protobuf::Message
public:
  
  inline void set_name(const ::std::string& value); //对应message的字段内容
  inline void set_email(const ::std::string& value);
  inline void set_id(::google::protobuf::int32 value);
  ...
}

第三步,编写C++业务代码:

// Person_Test.cpp
#include <iostream>
#include <fstream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include <fmt/core.h>
#include "person.pb.h"

using namespace test;

int main() {
    // 构造 Person 并填充信息
    Person p;
    p.set_name("Koshkaaa");
    p.set_id(100);
    p.set_email("[email protected]");

    // 将 pb 二进制信息保存到字符串, 序列化
    std::string str;
    p.SerializeToString(&str);
    fmt::print("str: [ {} ]\n", str);

    // 将 pb 文件信息写入文件
    std::ofstream  fw;
    fw.open("../Person.txt", std::ios::out | std::ios::binary);
    auto *out = new google::protobuf::io::OstreamOutputStream(&fw);
    google::protobuf::TextFormat::Print(p, out);

    delete out;
    fw.close();

    // 将 pb 文本信息保存到字符串
    std::string str1;
    google::protobuf::TextFormat::PrintToString(p, &str1);
    fmt::print("str1: [ {} ]\n", str1);

    // 反序列化
    Person p1;
    p1.ParseFromString(str);
    fmt::print("Person1: name {0}, email {1}, id {2}", p1.name(), p1.email(), p1.id());

    return 0;
}

Cpp 业务代码对应的 CMakeList.txt :

# 使用 VcPkg
# ./vcpkg install protobuf:[special-version]
cmake_minimum_required(VERSION 3.24)
project(protobuf_tutorial)

set(CMAKE_CXX_STANDARD 17)

find_package(protobuf CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED)

add_executable(protobuf_tutorial main.cpp
        person.pb.cc)

target_link_libraries(
        protobuf_tutorial
        PRIVATE
        protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite
        fmt::fmt
)

另一种可供的参考

# 未使用 VcPkg
cmake_minimum_required(VERSION 3.24)
project(protobuf_tutorial)
set(CMAKE_CXX_FLAGS "-std=c++11  ${CMAKE_CXX_FLAGS}")

find_package(Protobuf REQUIRED)
include_directories(
  include
  ${PROTOBUF_INCLUDE_DIRS}
)
add_library(addressbook_protobuf person.pb.cc)
add_executable(test_person test_person.cpp)
target_link_libraries(
    test_person 
    addressbook_protobuf
    ${PROTOBUF_LIBRARIES}
)

标签:set,Protobuf,proto,Person,person,Cpp,Party,include,protobuf
From: https://www.cnblogs.com/RioTian/p/17687338.html

相关文章

  • windows vs使用grpc-cpp的坑
    1.通过vcpkg安装protoc和grpc-cpp2.生成proto协议代码:protoc-I..-I.--cpp_out=. test.proto3.生成grpc服务代码:protoc-I..-I.--grpc_out=.--plugin=protoc-gen-grpc=`full_path\grpc_cpp_plugin.exe` test.proto4.创建vs工程,引用生成的代码,引用vcpkg安装的pro......
  • 使用Nodejs的addon导入cpp生成的dll时出现的问题记录
    在使用Nodejs的addon导入自己编写的cpp的dll时出现的一系列问题记录标签:__declspec、Napi、LoadLibraryA、GetLastError、dumpbin/exports。正常创建一个使用Napi的nodejsaddon项目(网上都有,在这里不赘述),主要代码如下:#include<napi.h>#include<iostream>#include<atlst......
  • 自留_CPP面向对象习题
    Question第一部分C++面向对象练习题1定义盒子类Box,包括三个private类型数据成员x,y,z,分别代表其长、宽、高。类中包括有参构造函数,计算体积的private类型成员函数volume和public类型显示函数display。在主函数中,定义对象box1(10,20,30),调用相关函数显示该盒子对象的长、宽、高......
  • JSONCPP向浏览器前端发送服务器本地文件列表
    服务器解析了浏览器请求之后,要进行响应响应体里需要存放请求的内容HTML标签:是页面的核心内容,定义了页面有什么内容。CSS:控制HTML元素的排版布局和展示方式,是美化页面文档的。JavaScript:让用户与页面进行交互,或在网页背后默默操控网页,以便让显示的内容与效果有所改变。对网页来......
  • SpringBoot使用protobuf格式的接口方式
    建立SpringBoot项目,pom.xml内容如下:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="......
  • protobuf语法风格
    文章目录一、代码风格二、文件格式三、包四、消息类型和字段五、repeated字段六、枚举类型七、服务一、代码风格每一行的代码长度不要超过80。使用两个空格进行缩进。二、文件格式文件命名应该采用蛇形命名法(即用下划线连接),如:lower_snake_case.proto。所有文件应以下列方式排列:Li......
  • cocos2dx 3.x C++搭建protobuf环境
    Cocos2dx里面在网络游戏通信这一块一般我们都会采用protobuf来进行通信,cocos引擎没有集成C++的protobuf,那我们只能自己来集成了。因为protobuf有很多版本,那么我们怎么去下载与引擎中想对应的protobuf版本呢。他在cocos2d-x\tools\simulator\libsimulator\lib\protobuf-lite在这里......
  • 使用protobuf()
    Protobuf的简介请看这里:哪我们来讲一下该如何使用1,首先去谷歌网站上下载(https://github.com/google/protobuf)我下载的是2.5版本的2,编译好工程,如图所示(挨个编译,注:test工程不需要编译),在编译protoc工程的时候,可能报错,1>main.obj:errorLNK2019:unresolvedexternalsymbol"p......
  • 报错test_features2d.cpp:51:10: fatal error: features2d/test/test_detectors_regre
    问题描述:ubuntu18.04安装opencv4.5.1+contrib报错test_features2d.cpp:51:10:fatalerror:features2d/test/test_detectors_regression.impl.hpp:没有那个文件或目录解决方法如题,报错如下:解决方法:按照报错提示,将opencv-4.5.1/modules中的features2d文件夹一整个复制到ope......
  • 【OpenCV】features2d_converters.cpp:2:10: fatal error: common.h: 没有那个文件或
    Linux环境下使用opencv的dnn模块调用yolov4遇到的坑(纯CPU)一、问题描述Ubuntu安装opencv4.4,第一次编译完成安装成功,发现编译时少加了几个选项,于是重新编译,结果报如下错误:opencv_contrib-4.4.0/modules/xfeatures2d/test/features2d/misc/java/src/cpp/\features2d_converters.cpp:......