使用fastdds替换原有协议为protobuf

proto定义

bash 复制代码
syntax = "proto3";

package example;

message MyMessage {
  int32 id = 1;
  string content = 2;
}

pub端

cpp 复制代码
#include <iostream>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "example.pb.h"

using namespace eprosima::fastdds::dds;

class ProtobufType : public TopicDataType {
public:
	ProtobufType() {
		setName("example::MyMessage");
		m_typeSize = 4 + 100; // Adjust size accordingly
		m_isGetKeyDefined = false;
	}

	bool serialize(void* data, eprosima::fastrtps::rtps::SerializedPayload_t* payload) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage;
		message->SerializeToString(&serializedMessage);
		payload->length = static_cast<uint32_t>(serializedMessage.size());
		memcpy(payload->data, serializedMessage.data(), payload->length);
		return true;
	}

	bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t* payload, void* data) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage(reinterpret_cast<char*>(payload->data), payload->length);
		return message->ParseFromString(serializedMessage);
	}

	std::function<uint32_t()> getSerializedSizeProvider(void* data) override {
		return [data]() -> uint32_t {
			example::MyMessage* message = static_cast<example::MyMessage*>(data);
			return static_cast<uint32_t>(message->ByteSizeLong());
		};
	}

	void* createData() override {
		return new example::MyMessage();
	}

	void deleteData(void* data) override {
		delete static_cast<example::MyMessage*>(data);
	}

	bool getKey(void* data, InstanceHandle_t* ihandle, bool force_md5 = false) override {
		return false;
	}
};

int main() {
	// 创建DomainParticipant
	DomainParticipantQos participantQos;
	DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

	if (participant == nullptr) {
		std::cerr << "创建DomainParticipant失败!" << std::endl;
		return 1;
	}

	// 注册类型
	TypeSupport myType(new ProtobufType());
	myType.register_type(participant);

	// 创建Topic
	TopicQos topicQos;
	Topic* topic = participant->create_topic("MyTopic", "example::MyMessage", topicQos);

	if (topic == nullptr) {
		std::cerr << "创建Topic失败!" << std::endl;
		return 1;
	}

	// 创建Publisher
	PublisherQos publisherQos;
	Publisher* publisher = participant->create_publisher(publisherQos);

	if (publisher == nullptr) {
		std::cerr << "创建Publisher失败!" << std::endl;
		return 1;
	}

	// 创建DataWriter
	DataWriterQos writerQos;
	DataWriter* writer = publisher->create_datawriter(topic, writerQos);

	if (writer == nullptr) {
		std::cerr << "创建DataWriter失败!" << std::endl;
		return 1;
	}
	std::this_thread::sleep_for(std::chrono::seconds(1));
	// 创建Protobuf消息
	example::MyMessage message;
	message.set_id(1);
	message.set_content("123");

	// 发布消息
	writer->write(&message);

	// 清理资源
	participant->delete_contained_entities();
	DomainParticipantFactory::get_instance()->delete_participant(participant);

	return 0;
}

SUB端

cpp 复制代码
#include <iostream>
#include <thread>
#include <chrono>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "example.pb.h"

using namespace eprosima::fastdds::dds;

class MyListener : public DataReaderListener {
	void on_data_available(DataReader* reader) override {
		example::MyMessage serializedMessage;
		SampleInfo info;

		// 读取数据
		if (reader->take_next_sample(&serializedMessage, &info) == ReturnCode_t::RETCODE_OK) {
			if (info.valid_data) {

				// 打印消息
				std::cout << "Received message: id=" << serializedMessage.id() << ", content=" << serializedMessage.content() << std::endl;
			}
		}
	}
};

class ProtobufType : public TopicDataType {
public:
	ProtobufType() {
		setName("example::MyMessage");
		m_typeSize = 4 + 100; // Adjust size accordingly
		m_isGetKeyDefined = false;
	}

	bool serialize(void* data, eprosima::fastrtps::rtps::SerializedPayload_t* payload) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage;
		message->SerializeToString(&serializedMessage);
		payload->length = static_cast<uint32_t>(serializedMessage.size());
		memcpy(payload->data, serializedMessage.data(), payload->length);
		return true;
	}

	bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t* payload, void* data) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage(reinterpret_cast<char*>(payload->data), payload->length-1);
		return message->ParseFromString(serializedMessage);
	}
	std::function<uint32_t()> getSerializedSizeProvider(void* data) override {
		return [data]() -> uint32_t {
			example::MyMessage* message = static_cast<example::MyMessage*>(data);
			return static_cast<uint32_t>(message->ByteSizeLong());
		};
	}

	void* createData() override {
		return new example::MyMessage();
	}

	void deleteData(void* data) override {
		delete static_cast<example::MyMessage*>(data);
	}

	bool getKey(void* data, eprosima::fastrtps::rtps::InstanceHandle_t* ihandle, bool force_md5 = false) override {
		// 对于此示例,我们假设不需要键(即,我们不使用基于键的过滤)  
		//*ihandle = eprosima::fastrtps::rtps::c_InstanceHandle_Unknown();
		return false;
	}

};

int main() {
	// 创建DomainParticipant
	DomainParticipantQos participantQos;
	DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

	if (participant == nullptr) {
		std::cerr << "创建DomainParticipant失败!" << std::endl;
		return 1;
	}

	// 注册类型
	TypeSupport myType(new ProtobufType());
	myType.register_type(participant);

	// 创建Topic
	TopicQos topicQos;
	Topic* topic = participant->create_topic("MyTopic", "example::MyMessage", topicQos);

	if (topic == nullptr) {
		std::cerr << "创建Topic失败!" << std::endl;
		return 1;
	}

	// 创建Subscriber
	SubscriberQos subscriberQos;
	Subscriber* subscriber = participant->create_subscriber(subscriberQos);

	if (subscriber == nullptr) {
		std::cerr << "创建Subscriber失败!" << std::endl;
		return 1;
	}

	// 创建DataReader
	DataReaderQos readerQos;
	DataReader* reader = subscriber->create_datareader(topic, readerQos, new MyListener());

	if (reader == nullptr) {
		std::cerr << "创建DataReader失败!" << std::endl;
		return 1;
	}

	// 等待接收消息
	std::cout << "Waiting for messages..." << std::endl;
	std::this_thread::sleep_for(std::chrono::minutes(100));

	// 清理资源
	participant->delete_contained_entities();
	DomainParticipantFactory::get_instance()->delete_participant(participant);

	return 0;
}
相关推荐
No0d1es1 小时前
2025年 CSP-J1 入门级初赛 C++真题
开发语言·c++·青少年编程·csp·信息学奥赛·初赛
橙子也要努力变强1 小时前
C++中的多态
c++
ysa0510302 小时前
虚拟位置映射(标签鸽
数据结构·c++·笔记·算法
m0_748248022 小时前
C++中的位运算符:与、或、异或详解
java·c++·算法
草莓熊Lotso3 小时前
C++ 方向 Web 自动化测试实战:以博客系统为例,从用例到报告全流程解析
前端·网络·c++·人工智能·后端·python·功能测试
共享家95274 小时前
LRU 缓存的设计与实现
开发语言·c++
草莓熊Lotso4 小时前
Linux 基础开发工具入门:软件包管理器的全方位实操指南
linux·运维·服务器·c++·人工智能·网络协议·rpc
小龙报4 小时前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
晨非辰5 小时前
【数据结构初阶】--从排序算法原理分析到代码实现操作,参透插入排序的奥秘!
c语言·开发语言·数据结构·c++·算法·面试·排序算法
2301_795167209 小时前
玩转Rust高级应用 如何避免对空指针做“解引用”操作,在C/C++ 里面就是未定义行为
c语言·c++·rust