protobuf+msgpack使用笔记

Protobuf安装

参考链接
其他版本:
3.13.0

Protobuf python接口使用

参考链接

Protobuf+Msgpack C++接口使用

写一个proto文件,plan.proto

syntax = "proto3";
package robot;
message Path {
    uint32 move_direct = 4; 
    float turn_radius = 5;
    float move_distance = 6;                     
}
message Pose {
    float x = 3;
    float y = 4;
}
// topic : "planning"
message Planning {
    uint64 timestamp = 1; 
    Pose start_pose = 3;
    repeated Path planning_path = 5;
}

生成c++文件

# 单个
protoc plan.proto --cpp_out=./
# 多个文件时
ls . |grep ".proto" |xargs -n 1 protoc -I=. --cpp_out=../proto_cpp

序列化和反序列化

#include "planning.pb.h"
using namespace std;
int mian()
{
	// 【1】填充数据
	robot::Planning planPB;
	// uint64 timestamp = 1; 
	planPB.set_timestamp(165555555);
	// repeated Path planning_path = 5;
	robot::Path *p1 = planPB.add_planning_path();
	p1->set_move_direct(1);
	p1->set_turn_radius(10);
	p1->set_move_distance(M_PI/2*10);
	
	planPB.add_planning_path()->set_move_direct(0);
	// Pose start_pose = 3;
	robot::Pose* pose = planPB.mutable_start_pose();
	pose->set_x(1);
	pose->set_y(2);
	
	// 【2】pb序列化
	string enc;
	planPB.SerializeToString(&enc);
	// msgpack序列化
	msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, enc); 
    cout << sbuf.size() << endl;
    // 【3】msgpack序列化
    auto handle = msgpack::unpack(          // 反序列化
                sbuf.data(), sbuf.size());  // 输入二进制数据
    auto obj = handle.get();                // 得到反序列化对象
    string dec;
    obj.convert(dec);// 转换反序列化的数据
	// 【4】反序列化
	robot::Planning planMsg;
	planMsg.ParseFromString(dec);
	// 【5】读取数据
	int timestamp = planMsg.timestamp();
	float x = planMsg.start_pose().x();
	for (size_t i = 0; i < planMsg.planning_path_size(); i++)
	{
	    size_t moveDirect = planMsg.planning_path(i).move_direct();
	    float turnRadius = planMsg.planning_path(i).turn_radius();
	    float moveDistance = planMsg.planning_path(i).move_distance();
	}
}

编译

cmake_minimum_required(VERSION 3.0.2)
project(test)

set(msgpack_INCLUDE_DIRS ./third_party/msgpack_2_1_5/include)
set(protobuf_libs_DIR ./third_party/protobuff_3_13_0/lib)
set(protobuf_INCLUDE_DIRS ./third_party/protobuff_3_13_0/include)

aux_source_directory(./third_party/proto_cpp/ PROTO_CPP)

include_directories(
  ${msgpack_INCLUDE_DIRS}
  ${protobuf_INCLUDE_DIRS}
  ./third_party/include
  ./third_party/proto_cpp/
)

link_directories(
  ${protobuf_libs_DIR}
  ./third_party/lib  # lib: 库文件的相对路径
)

add_executable(test mian.cpp ${PROTO_CPP})

target_link_libraries(test
    protobuf
)
mkdir build && cd build && cmake .. && make

msgpack

C++ 自定义数据结构时的使用用法
python接口

Protobuf 转 Json

C++

#include 
#include 
#include  //proto2json

#include "Planning.pb.h"

bool Proto2Json(const google::protobuf::Message& message, std::string& json)
{
  google::protobuf::util::JsonPrintOptions options;
  options.add_whitespace = true;
  options.always_print_primitive_fields = true;
  return MessageToJsonString(message, &json, options).ok();
}
int main()
{
	// 【1】填充数据
	robot::Planning planPB;
	// uint64 timestamp = 1; 
	planPB.set_timestamp(165555555);
	// repeated Path planning_path = 5;
	robot::Path *p1 = planPB.add_planning_path();
	p1->set_move_direct(1);
	p1->set_turn_radius(10);
	p1->set_move_distance(M_PI/2*10);
	
	planPB.add_planning_path()->set_move_direct(0);
	// Pose start_pose = 3;
	robot::Pose* pose = planPB.mutable_start_pose();
	pose->set_x(1);
	pose->set_y(2);
	
	// 【2】pb序列化
	string enc;
	planPB.SerializeToString(&enc);
	// msgpack序列化
	msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, enc); 
    cout << sbuf.size() << endl;
    // 【3】msgpack序列化
    auto handle = msgpack::unpack(          // 反序列化
                sbuf.data(), sbuf.size());  // 输入二进制数据
    auto obj = handle.get();                // 得到反序列化对象
    string dec;
    obj.convert(dec);// 转换反序列化的数据
	// 【4】反序列化
	robot::Planning planMsg;
	planMsg.ParseFromString(dec);
	// 【5】读取数据
	int timestamp = planMsg.timestamp();
	float x = planMsg.start_pose().x();
	for (size_t i = 0; i < planMsg.planning_path_size(); i++)
	{
	    size_t moveDirect = planMsg.planning_path(i).move_direct();
	    float turnRadius = planMsg.planning_path(i).turn_radius();
	    float moveDistance = planMsg.planning_path(i).move_distance();
	}
	// 【6】转json并存储
	std::string msg1savePath = "./msg1.json";
	std::ofstream msg1(msg1savePath);
	std::string jsonString;
	Proto2Json(planMsg, jsonString);
	msg1 << std::setw(4) << jsonString << "," << std::endl;
	msg1.close();
	return 0;
}

python

from google.protobuf import json_format
import Planning_pb2
import json

#【1】填充数据
msg = Planning_pb2.Planning()
path = msg.planning_path.add()

path.move_direct = 0;
path.turn_radius = -2;
path.move_direct = 3;

msg.timestamp = 1666666666333
msg.start_pose.x = 0
msg.start_pose.y = 0
#【2】pb序列化
serializeToString = msg.SerializeToString()
print(serializeToString,type(serializeToString))

# 【3】 反序列化
msg.ParseFromString(serializeToString)
# 【4】取值
for path in msg.planning_path:
	print(path.move_direct)
print(msg.timestamp)
# 【5】转json存本地
save_result = open(file =./plan.txt’, mode = 'w')
plan_json = json_format.MessageToDict(msg, preserving_proto_field_name=True)
save_result.write(json.dumps(plan_json))
save_result.close()

参考

你可能感兴趣的:(python工具,c++工具,c++)