Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序

这篇具有很好参考价值的文章主要介绍了Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、创建简单示例程序

在这里,先建立一个IDL文件,然后通过使用Fast DDS-Gen生成程序生成这个简单示例程序。Fast DDS-Gen程序的编译安装请参考《Fast DDS入门二、Fast DDS在Windows平台的编译安装》,Fast DDS-Gen程序的使用请参考《Fast DDS入门四、Fast DDS-Gen使用介绍》。

(1)创建IDL文件

先建立一个单独的目录HelloWorldExample,在该目录下建立IDL文件和生成示例程序的c++源程序文件。

本示例构建最小的应用程序,必须通过IDL文件定义Topic。在本例中,IDL定义的Topic数据类型只是一个字符串消息。在首选文本编辑器中,创建具有以下内容的HelloWorld.IDL文件,并将其保存在HelloWorldExample目录中。

// HelloWorld.IDL

struct HelloWorld

{

string message;

};

(2)Fast DDS-Gen生成示例程序源码

然后,将此文件转换为Fast DDS能够理解的内容。为此,使用Fast DDS Gen代码生成工具,它可以执行生成示例的操作。执行如下命令:

fastddsgen.bat -example CMake HelloWorld.IDL

执行命令成功结束后,会产生一系列源文件,如下所示:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

(3)CMake配置生成vs解决方案

Fast DDS-Gen生成示例程序源码后,生成了系列的.h、.cxx源文件,同时生成了CMakeLists.txt文件。因此可以通过CMake配置示例程序的依赖项目生成vs解决方案,然后通过vs编译生成可执行程序。相关依赖项的编译生成可参考《Fast DDS入门二、Fast DDS在Windows平台的编译安装》,以下为CMake界面程序的配置参考:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

Configure和generate成功后,在out子目录下生成了项目、解决方案等文件,在out目录下可看到如下:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

2、示例代码分析及编译运行

用vs打开CMake生成的generated_code.sln解决方案,如下图所示:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

可以看到有4个项目,其中源码项目是:HelloWorld_lib和HelloWorld项目。HelloWorld_lib项目包含IDL生成的结构体类HelloWorld.h和HelloWorld.cxx,这个项目生成lib静态库。HelloWorld项目,依赖于HelloWorld_lib项目,可生成发布/订阅可执行程序。

(1)源代码分析

HelloWorld_lib项目的HelloWorld类,主要实现了IDL定义结构体类型的序列化和反序列化,头文件简要如下:

class HelloWorld
{
public: 
   /*!
    * @brief This function serializes an object using CDR serialization.
    * @param cdr CDR serialization object.
    */
   eProsima_user_DllExport void serialize(
            eprosima::fastcdr::Cdr& cdr) const;
 
   /*!
    * @brief This function deserializes an object using CDR serialization.
    * @param cdr CDR serialization object.
    */
   eProsima_user_DllExport void deserialize(
            eprosima::fastcdr::Cdr& cdr);
 
private:
   std::stringm_message;
};

HelloWorld项目的HelloWorldPubSubType类是HelloWorld类的封装类,其继承自TopicDataType类,该类可注册到Fast DDS中,序列化和反序列化函数是vitual函数在父类中声明,在子类中实现,在发布订阅函数中实现回调处理,发布时将HelloWorld类序列化并通过socket发送,订阅时通过socket接收到二进制后执行HelloWorld类的反序列化,以下为HelloWorldPubSubType类的核心代码:

bool HelloWorldPubSubType::serialize( //序列化函数
       void* data,
       SerializedPayload_t* payload)
{
   HelloWorld* p_type= static_cast<HelloWorld*>(data);
   // Object that manages the raw buffer.
   eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload->data), payload->max_size);
   // Object that serializes the data.
   eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,eprosima::fastcdr::Cdr::DDS_CDR);
   payload->encapsulation= ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
   // Serialize encapsulation
   ser.serialize_encapsulation();
   try
   {
       // Serialize the object.
       p_type->serialize(ser);
   }
   catch(eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/)
   {
       return false;
   }
 
   // Get the serialized length
   payload->length= static_cast<uint32_t>(ser.getSerializedDataLength());
    return true;
}
 
bool HelloWorldPubSubType::deserialize(  //反序列化函数
       SerializedPayload_t* payload,
       void* data)
{
   try
   {
       //Convert DATA to pointer of your type
       HelloWorld* p_type= static_cast<HelloWorld*>(data);
       // Object that manages the raw buffer.
       eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload->data), payload->length);
       // Object that deserializes the data.
       eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,eprosima::fastcdr::Cdr::DDS_CDR);
       // Deserialize encapsulation.
       deser.read_encapsulation();
       payload->encapsulation= deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
       // Deserialize the object.
       p_type->deserialize(deser);
   }
   catch(eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/)
   {
       return false;
   }
   return true;
}

HelloWorld项目的发布订阅类分别是:HelloWorldPublisher类和HelloWorldSubscriber类。发布类的核心源码有两个重要的成员函数,初始化函数init()和发送数据函数run(),代码如下所示:

bool HelloWorldPublisher::init()  //初始化函数
{
   /* Initialize data_ here */
   //CREATE THE PARTICIPANT
   DomainParticipantQos pqos;
   pqos.name("Participant_pub");
   participant_ = DomainParticipantFactory::get_instance()->create_participant(0, pqos);
   if(participant_ == nullptr)
   {
       return false;
   }
   //REGISTER THE TYPE
   type_.register_type(participant_);
   //CREATE THE PUBLISHER
   publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
   if(publisher_ == nullptr)
   {
       return false;
   }
   //CREATE THE TOPIC
   topic_ = participant_->create_topic(
       "HelloWorldTopic",
       type_.get_type_name(),
       TOPIC_QOS_DEFAULT);
   if (topic_== nullptr)
   {
       return false;
   }
   // CREATE THE WRITER
   writer_ = publisher_->create_datawriter(topic_,DATAWRITER_QOS_DEFAULT, &listener_);
   if(writer_ == nullptr)
   {
       return false;
   }
   std::cout << "HelloWorld DataWriter created." << std::endl;
   return true;
}

发布者的初始化函数,首先创建参与者participant,参与者participant是publisher和subscriber的容器,可用来创建发布者和订阅者。之后参与者注册HelloWorld的数据类型,创建publisher,创建topic主题,最后通过发布者publisher创建写入器writer,通过writer可直接发送数据。

void HelloWorldPublisher::run()  //运行函数发送数据
{
   std::cout << "HelloWorld DataWriter waiting forDataReaders." << std::endl;
   while(listener_.matched == 0)
   {
       std::this_thread::sleep_for(std::chrono::milliseconds(250)); // Sleep 250 ms
   }
   // Publication code
   HelloWorld st;
   /* Initialize your structure here */
   int msgsent= 0;
   char ch = 'y';
   do
   {
       if (ch == 'y')
       {
            writer_->write(&st);
            ++msgsent;
            std::cout << "Sendingsample, count=" << msgsent << ", sendanother sample?(y-yes,n-stop): ";
       }
       else if (ch == 'n')
       {
            std::cout << "Stoppingexecution " << std::endl;
            break;
       }
       else
       {
            std::cout << "Command" << ch << " notrecognized, please enter \"y/n\":";
       }
   } while(std::cin >> ch);
}

发送数据函数通过publisher的写入器writer直接发送HelloWorld类型的数据st。

订阅类的核心源码也有两个重要的成员函数,初始化函数init()和其订阅监听器子类成员函数SubListener::on_data_available(),Init()成员函数雷同于publisher的init()成员函数,只不过是subscriber的init()函数是建立订阅者subscriber和监听器listener,通过监听器回调接收订阅的数据。

监听器SubListener::on_data_available()数据接收代码如下所示:

void HelloWorldSubscriber::SubListener::on_data_available(  //监听接收数据函数
       DataReader* reader)
{
   // Take data
   HelloWorld st;
   SampleInfo info;
 
   if (reader->take_next_sample(&st,&info) == ReturnCode_t::RETCODE_OK)
   {
       if(info.valid_data)
       {
            // Printyour structure data here.
            ++samples;
            std::cout << "Samplereceived, count=" << samples << std::endl;
       }
   }
}

on_data_available()函数,是监听器的回调函数,被订阅者subscriber的阅读器reader接收到数据后,将socket接收的二进制数据反序列化成HelloWorld类数据,是开发人员的订阅接收数据入口。

(2)编译运行可执行程序

在vs开发工具中执行build命令,将在out/debug或release目录下生成可执行二进制文件HelloWorld.exe,同时将其依赖的库文件也拷贝到这里。如下所示:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

然后通过powershell执行两个HelloWorld.exe命令,第一个命令后面空格后输入subscriber字符,第二个命令后面空格后输入publisher字符,发布程序和订阅程序将能够正常运行。运行界面如下所示:

fastdds,Fast DDS入门,网络协议,Powered by 金山文档

至此,Fast DDS的简单发布订阅示例程序的创建、编译、运行就成功结束了。

CSDN下载:免费下载Fast DDS简单发布订阅示例程序源码

github下载:git clone https://github.com/FantasticSaltedFish/Fast-DDS.git文章来源地址https://www.toymoban.com/news/detail-603865.html

到了这里,关于Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Fast DDS入门四、Fast DDS-Gen使用介绍

    Fast DDS-Gen是一个Java应用程序,它使用IDL(接口定义语言)文件中定义的数据类型生成Fast DDS源代码。生成的源代码可以用于任何Fast DDS应用程序中,以定义主题的数据类型,并且将用于发布或订阅。Fast DDS通过两个类定义Topic中交换的数据类型:TypeSupport和TopicDataType。TopicData

    2024年02月15日
    浏览(34)
  • 使用Flask Web创建一个调用ChatGPT API的网页--简单示例(linux环境下)

    前提:你应该要有一个能正常使用chatGPT的openAI账号;即你已经成功注册了chatGPT,并能正常使用。 下面是一个使用Flask Web框架创建调用ChatGPT API的网页的示例代码和工程结构: 具体的工程,你可以选择自己创建,也可以直接下载我创建好的工程,链接如下: https://download.csd

    2024年02月13日
    浏览(39)
  • Visual Studio 2019 C# 上位机入门(1):如何创建工程编写一个简单应用

    Visual Studio 2019下载安装步骤可以看:https://blog.csdn.net/weixin_44788542/article/details/114271126 这里不赘述,默认电脑上已经安装好了。 1、打开安装好的Visual Studio后,选择创建新项目。 2、找到选择C#下面的Windows 窗体应用,然后下一步起名和文件存放位置 如果找不到Windows 窗体应用,

    2024年02月05日
    浏览(54)
  • 【Scala入门】Scala下载及安装(Windows)以及Idea创建第一个scala项目

    目录 一、安装准备 二、Scala下载安装 三、Idea 创建Scala项目 在安装之前,确保你的电脑上装有Jdk 8(Jdk 1.8),且环境变量配置正确。如果没有安装Jdk,请参照其他文章先安装Jdk 8(Jdk 1.8)。 (1)确认环境变量方法:使用Win + R 快捷键调出下面窗口,输入“cmd”,按下回车。

    2024年02月05日
    浏览(52)
  • 一个简单的spdlog使用示例

    目录 引用源码 封装Log头文件 使用方法 spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://github.com/gabime/spdlog。 先下载spdlog的源码,将源码的include文件夹复制到自己的项目文件夹下: 然后在项目属

    2024年02月11日
    浏览(39)
  • C++ Windows Socket 简单示例

    2024年02月09日
    浏览(32)
  • Kafka-入门及简单示例

    结果 一个生产者 一个消费者 生产者在某些事件时触发消息产生 消费者根据topic监听事件 如果有生产者产生消息 自动进行消费

    2024年02月05日
    浏览(36)
  • 一个简单的转账场景示例带你了解并发安全?

    本文转帐场景主要参考来自于极客时间 王老师的 《Java 并发编程实战》 一个简单的转账场景示例带你了解并发安全? 例如如银行业务里面的转账操作,账户 A 减少 100 元,账户 B 增加 100 元。 我们声明了个账户类:Account,该类有一个成员变量余额:balance,还有一个用于转账

    2024年01月22日
    浏览(46)
  • 不同微服务之间如何实现远程调用?一个简单示例告诉你

    目录 1、服务拆分原则  2、服务拆分示例 2.1、初始化数据库 2.2、导入demo工程 2.3、测试 3、实现远程调用 3.1、需求 3.2、注册RestTemplate 3.3、实现远程调用 4、提供者与消费者 5、代码免费分享 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习

    2024年04月27日
    浏览(37)
  • FAST协议解析3 FIX Fast Tutorial翻译 HelloWorld示例

    Fields in FAST do not have a fixed size and do not use a field separator. Instead, there is a notion of a stop bit (the high order bit on each byte of the message acts as a stop bit) signaling the end of the field. All of the above concepts used together allow the sender to compress a message (sometimes as much as 90%) and the receiver to restore the origina

    2024年02月03日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包