fastdds是一套开源的又C++开发的基于DDS通讯协议的中间件。因为项目需要,需要在B/S项目中使用,我们采用的是C#开发,所以如何打通如何在C#中使用fastdds,下面就是实现的过程:

首先,我们需要下载fastdds的源码,我是直接下载到一个eProsima_Fast-DDS-2.10.0-Windows.exe,安装包的方式安装代码以及需要的东西,这个方式其实就是把代码包装成安装包,所以下载源码和这个是基本一致的。

1)前提条件

在Windows环境中从源安装FastDDS需要在系统中安装以下工具:

Visual Studio

Chocolatey

CMake、pip3、wget和git

Gtest[可选]

具体安装就不做过多介绍,其实我主要用到的是vs2022,和CMake。

vs2022需要安装支持c++开发的功能模块

2)安装

eProsima_Fast-DDS-2.10.0-Windows.exe 安装完成后,会在目录下生成项目文件夹,如下图所示:

examples就是该中间件使用的详细例子文件夹。例子路径:

F:\Program Files\eProsima\fastrtps 2.10.0\examples\cpp\dds

接下来,我们需要对所有的例子进行生成可以以vs打开的项目,我们需要在上免得路径下进入命令窗体,

然后依次执行如下命令:


mkdir build
cd build
cmake ..//cmake ..可以换成下面这句,这是官网的推荐
cmake -Bbuildexample -DFASTDDS_STATIC=ON .

就可以在build文件夹下生成所有实例的项目文件,用vs可以打开。

关于上面项目能否正常运行的问题,请参考进行处理:Windows下运行Fast DDS示例程序(包含.idl文件的使用方法)_fastdds_Eliza_Her的博客-CSDN博客

接下来,就是对一些可以用到的实例进行简单处理,生成可以被C#调用的动态库。

我们新建一个C++的动态库项目,将HelloWorldExample的例子进行处理,引入需要的文件,结构如下:

其中FastDDSWrapper.h,FastDDSWrapper.cpp文件时新建的,其他的都是用的 HelloWorldExample的文件。

FastDDSWrapper.h

#pragma once
#include "pch.h"#define FASTDDSWRAPPER_EXPORTS true#ifdef FASTDDSWRAPPER_EXPORTS
#define FASTDDSWRAPPER_API __declspec(dllexport)
#else
#define FASTDDSWRAPPER_API __declspec(dllimport)
#endifextern "C" {FASTDDSWRAPPER_API int init_publisher(bool use_env);FASTDDSWRAPPER_API int publish(const char* message);FASTDDSWRAPPER_API int init_subscriber();FASTDDSWRAPPER_API int subscribe(char* buffer, int bufferSize);
}

FastDDSWrapper.cpp

// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License./*** @file HelloWorldPublisher.cpp**/
#include "pch.h"
#include "HelloWorldPublisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>#include <thread>using namespace eprosima::fastdds::dds;HelloWorldPublisher::HelloWorldPublisher(): participant_(nullptr), publisher_(nullptr), topic_(nullptr), writer_(nullptr), type_(new HelloWorldPubSubType())
{
}bool HelloWorldPublisher::init(bool use_env)
{hello_.index(0);hello_.message("HelloWorld");DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;pqos.name("Participant_pub");auto factory = DomainParticipantFactory::get_instance();if (use_env){factory->load_profiles();factory->get_default_participant_qos(pqos);}participant_ = factory->create_participant(0, pqos);if (participant_ == nullptr){return false;}//REGISTER THE TYPEtype_.register_type(participant_);//CREATE THE PUBLISHERPublisherQos pubqos = PUBLISHER_QOS_DEFAULT;if (use_env){participant_->get_default_publisher_qos(pubqos);}publisher_ = participant_->create_publisher(pubqos,nullptr);if (publisher_ == nullptr){return false;}//CREATE THE TOPICTopicQos tqos = TOPIC_QOS_DEFAULT;if (use_env){participant_->get_default_topic_qos(tqos);}topic_ = participant_->create_topic("HelloWorldTopic","HelloWorld",tqos);if (topic_ == nullptr){return false;}// CREATE THE WRITERDataWriterQos wqos = DATAWRITER_QOS_DEFAULT;if (use_env){publisher_->get_default_datawriter_qos(wqos);}writer_ = publisher_->create_datawriter(topic_,wqos,&listener_);if (writer_ == nullptr){return false;}return true;
}HelloWorldPublisher::~HelloWorldPublisher()
{if (writer_ != nullptr){publisher_->delete_datawriter(writer_);}if (publisher_ != nullptr){participant_->delete_publisher(publisher_);}if (topic_ != nullptr){participant_->delete_topic(topic_);}DomainParticipantFactory::get_instance()->delete_participant(participant_);
}void HelloWorldPublisher::PubListener::on_publication_matched(eprosima::fastdds::dds::DataWriter*,const eprosima::fastdds::dds::PublicationMatchedStatus& info)
{if (info.current_count_change == 1){matched_ = info.total_count;firstConnected_ = true;std::cout << "Publisher matched." << std::endl;}else if (info.current_count_change == -1){matched_ = info.total_count;std::cout << "Publisher unmatched." << std::endl;}else{std::cout << info.current_count_change<< " is not a valid value for PublicationMatchedStatus current count change" << std::endl;}
}void HelloWorldPublisher::runThread(uint32_t samples,uint32_t sleep)
{if (samples == 0){while (!stop_){if (publish(false)){std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()<< " SENT" << std::endl;}std::this_thread::sleep_for(std::chrono::milliseconds(sleep));}}else{for (uint32_t i = 0; i < samples; ++i){if (!publish()){--i;}else{std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()<< " SENT" << std::endl;}std::this_thread::sleep_for(std::chrono::milliseconds(sleep));}}
}void HelloWorldPublisher::run(uint32_t samples,uint32_t sleep)
{stop_ = false;std::thread thread(&HelloWorldPublisher::runThread, this, samples, sleep);if (samples == 0){std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;std::cin.ignore();stop_ = true;}else{std::cout << "Publisher running " << samples << " samples." << std::endl;}thread.join();
}bool HelloWorldPublisher::publish(bool waitForListener)
{if (listener_.firstConnected_ || !waitForListener || listener_.matched_ > 0){hello_.index(hello_.index() + 1);writer_->write(&hello_);return true;}return false;
}

这两个时对方法的再次封装处理。

都处理完成后,最重要的步骤需要对项目进行配置,要不然无法编译通过,如下所示:

以上需要配置的都是添加,不要删除项目原有的,不要删除项目原有的,不要删除项目原有的,添加的东西依次为:

包含目录:F:\Program Files\eProsima\fastrtps 2.10.0\include

库目录:F:\Program Files\eProsima\fastrtps 2.10.0\lib\x64Win64VS2019

链接器-输入-附加依赖项:F:\Program Files\eProsima\fastrtps 2.10.0\lib\x64Win64VS2019\fastrtps-2.10.lib;F:\Program Files\eProsima\fastrtps 2.10.0\lib\x64Win64VS2019\libfastcdr-1.0.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib

上面标红的都是根据自己安装fastdds的实例调整路径。

都配置完成后,修改

需要release ,然后编译。到此,就可以生成需要的.dll文件。

3)C#调用

建立C# 控制台程序,调用生成的.dll文件,

同时运行两个项目,就可以使用了。

内容补充:关于在windows下如何根据.idl 文件内容的结构体生成对应的fastdds核心的代码,基于上面已经通过步骤2 “eProsima_Fast-DDS-2.10.0-Windows.exe”安装的,安装完成后可以在安装路径下看到如下内容:

到此之后,就可以新建一个文件夹,里面建立一个HelloWorld.idl文件(需要生成代码的结构体),在该文件的路径下通过cmd命令进入到命令窗体,执行如下命令:

fastddsgen.bat -example CMake HelloWorld.idl -ppDisable

注意后面的参数“ -ppDisable” ,意思是

  • 如果您的 idl 上没有预处理器指令,请使用-ppDisable

如上图所示,表示已经自动生成了需要的代码文件,如下图所示:

到此时,就可以直接在继续在cmd命令窗体执行如下命令:

cmake -Bbuildexample -DFASTDDS_STATIC=ON .

注意参数:-Bbuildexample 是将生成的vs代码放在当前路径下新建的buildexample文件夹下。

生成的代码如下:

,可以以用vs2022打开,安装上面的步骤进行编译。

过程中需要的安装文件下载地址如下:

链接:https://pan.baidu.com/s/1xVN_mDjb3pIRJynx0bHluQ?pwd=ewfn 
提取码:ewfn

关于FastDDS在C#中使用的简单实例相关推荐

  1. Linux/Unix中的重定向简单实例

    "重定向"是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变.令程序与文件一同工作的方式有两种:一种是明确地使用打开文件.关闭文件.读文件.写文件等专门的函数(比如f ...

  2. POI之PPT中生成表格简单实例

    开心一笑 昨晚被一道神题考住了! ( )( ) ( )2 4 6 7 8 让我填空-我按照数列组合算了一下午都不对 最后, 答案是这样的 (门前大桥下)(游过一群鸭) (快来快来数一数) 2 4 6 ...

  3. Android多媒体学习一:Android中Image的简单实例。

    在多媒体应用中,Image是最基础的功能模块,接下来我们将看看在Android中是如何获取和存储Image的.Android内嵌的Image获取和存储功能,可以让我们对于整个媒体框架有个比较全面的了解 ...

  4. PS中蒙版使用简单实例

    首先双击PS工作区打开修改图片 接下来在工具栏中选中 矩形选择工具 并把羽化值设为25px  选出要操作的部分  选好之后 , 查看前景色和背景色是否为黑白色 如果不是的话就调为黑白色 然后同时按下 ...

  5. android surface编程,Android中SurfaceView用法简单实例

    本文实例讲述了Android中SurfaceView用法.分享给大家供大家参考,具体如下: 这里贴上一个小程序代码,主要运用SurfaceView来实现在屏幕上画一个圆,你可以通过按方向键和触摸屏幕来 ...

  6. django中使用celery简单介绍

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 本章节我们重点在于实现,如何存储任务的结果. 我们将任务函数改为: from celery_demo.celery im ...

  7. python tkinter库、添加gui界面_使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)...

    使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二),创建一个,界面,布局,文件,路径 使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二) ...

  8. php 在数组中,PHP 在数组中搜索给定的简单实例 array_search 函数

    array_search() PHP array_search() 函数用于在数组中搜索给定的值,如果成功则返回相应的键名,否则返回 FALSE . 语法: mixed array_search( m ...

  9. python实现简单的api接口-python中接口的实现实例

    接口基础知识: 简单说下接口测试,现在常用的2种接口就是http api和rpc协议的接口,今天主要说:http api接口是走http协议通过路径来区分调用的方法,请求报文格式都是key-value ...

  10. C及C++中typedef的简单使用指南

    C及C++中typedef的简单使用指南 又是在学数据结构的时候,发现了之前学习的知识遗忘很多,在发现对C/C++中关键字typedef的理解还是没有到位后,我翻阅了学C++用到的课本,又问了度娘,也 ...

最新文章

  1. 为什么要学习 Markdown?究竟有什么用?
  2. 学生每日计划表_早上6:13,很多教室的灯就亮了!高考还有10天,你都想象不到这些学生有多拼...
  3. Java基础学习总结(24)——Java单元测试之JUnit4详解
  4. vue 项目:文件夹 结构 、配置详解
  5. 白鹭引擎写入文字图层方法实例
  6. substr 与 substring 的区别
  7. c查看变量类型_Python入门对象与变量
  8. C++题解:百钱买百鸡数量
  9. excel 对列数据进行去重操作
  10. JS·经典·炫彩菜单(动画效果) for jquery
  11. android studio(as)找不到手机
  12. 读吴军老师的《浪潮之巅》总结
  13. 软考系统设计架构师经验与教训分享
  14. 使用vue.js实现一款简易计算器可多则混合运算(加减乘除)
  15. 大数据与会计专业群门户网站开发技术参数详解之博奥智源
  16. kubernetes-整体概述和架构
  17. centos修改磁盘uuid_磁盘UUID以及卷标
  18. scala aggregate
  19. 手把手教你配置Auto CAD左手快捷键
  20. 把当前自己使用的ubuntu系统做成镜像

热门文章

  1. flutter1.12回退1.9,升级请慎重
  2. 饥荒联机版联机显示服务器无应答,饥荒联机版水中木更新内容汇总 8月13日更新预览...
  3. 买二手楼要擦亮双眼——程序猿买二手房必看案例
  4. MQTT 发布、订阅和取消订阅 -MQTT要点:第 4 部分
  5. C和C++里面的struct有什么区别
  6. VMware 安装 Windows10(各种版本)【保姆级】
  7. python 二手车数据分析以及价格预测
  8. php 代码规范,PHP代码规范
  9. MySQL 学习笔记 JSON 类型
  10. 2021年安全员-B证(陕西省)考试报名及安全员-B证(陕西省)考试平台