基于OpenDDS的应用开发,主要分两个部分的工作:

(1)定义自己的IDL文件,并编译成消息数据类型通讯动态库;

(2)分别编写pub和sub程序,运行

具体步骤,有以下几个:

  1. 定义idl文件,如HelloMsg.ild
  2. 运行脚本,产生相应的消息类型符号导出头文件HelloMsgCommon_Export.h
  3. 编写mwc、mpc工作台和项目文件,如HelloMsg.mwc、HelloMsg.mpc
  4. 编译mpc文件,产生解决方案和工程,如HelloMsg.sln、HelloMsgCommon.vcxproj、HelloMsgPub.vcxproj、HelloMsgSub.vcxproj
  5. 编写HelloMsgPub.cpp和HelloMsgSub.cpp代码;
  6. 编译工程,产生动态库HelloMsgCommon.dll、HelloMsgPub.exe、HelloMsgSub.exe
  7. 运行发布和订阅程序,查看运行结果

下面,展开来看。。。

步骤一、定义HelloMsg.idl


module Hello
{#pragma DCPS_DATA_TYPE "Hello::HelloMsg"#pragma DCPS_DATA_KEY "Hello::HelloMsg msg"struct HelloMsg{string msg;};
};

步骤二、制作HelloMsg消息导出符号头文件HelloMsgCommon_Export.h

perl %ACE_ROOT%/bin/generate_export_file.pl HelloMsgCommon > HelloMsgCommon_Export.h

步骤三、定义HelloMsg.mwc、HelloMsg.mpc

workspace {// the -relative and -include cmdlines make it so this workspace // does not have to be in the $DDS_ROOT directory tree.// tell MPC to substitute our DDS_ROOT environment variables for relative pathscmdline += -relative DDS_ROOT=$DDS_ROOT// tell the projects where to find the DDS base projects (*.mpb)cmdline += -include $DDS_ROOT/MPC/config}
project(*Common) : dcps {sharedname     = HelloMsgCommondynamicflags   = HELLOMSGCOMMON_BUILD_DLLlibout         = .requires += tao_orbsvcsrequires += no_opendds_safety_profileafter    += Svc_Utilsincludes      += $(TAO_ROOT)/orbsvcsidlflags      += -I$(TAO_ROOT)/orbsvcs \-Wb,export_macro=HelloMsgCommon_Export \-Wb,export_include=HelloMsgCommon_Export.hdcps_ts_flags += -Wb,export_macro=HelloMsgCommon_ExportTypeSupport_Files {HelloMsg.idl}IDL_Files {HelloMsgTypeSupport.idlHelloMsg.idl}// We only want the generated filesHeader_Files {}// We only want the generated filesSource_Files {}
}project(HelloMsgPub) : dcpsexe, dcps_tcp, svc_utils {after    += *Commonexename   = HelloMsgPubrequires += tao_orbsvcsrequires += no_opendds_safety_profileincludes += $(TAO_ROOT)/orbsvcslibs     += HelloMsgCommonIDL_Files {}TypeSupport_Files {}Header_Files {}Source_Files {HelloMsgPub.cpp}Documentation_Files {dds_tcp_conf.inidds_udp_conf.ini}
}project(HelloMsgSub) : dcpsexe, dcps_tcp {after    += *Commonexename   = HelloMsgSubrequires += tao_orbsvcsrequires += no_opendds_safety_profileincludes += $(TAO_ROOT)/orbsvcslibs     += HelloMsgCommonTypeSupport_Files {}IDL_Files {}Header_Files {}Source_Files {HelloMsgSub.cpp}Documentation_Files {dds_tcp_conf.inidds_udp_conf.ini}
}

步骤四,产生vs2010的工程文件

    perl %ACE_ROOT%/bin/mwc.pl -type vc10 HelloMsg.mwc产生HelloMsg.sln、HelloMsg_Common.vcxproj、HelloMsgPub.vcxproj和HelloMsgSub.vcxproj

步骤五、编写HelloMsgPub.cpp和HelloMsgSub.cpp代码

HelloMsgPub.cpp

/******************************************************************  file:  HelloMsgPub.cpp*  desc:  Provides a simple C++ 'hello world' DDS publisher.*         This publishing application will send data*         to the example 'hello world' subscribing *         application (hello_sub).*  ****************************************************************/
#include <dds/DCPS/Service_Participant.h>
#include <dds/DCPS/Marked_Default_Qos.h>
#include <dds/DCPS/PublisherImpl.h>
#include "dds/DCPS/StaticIncludes.h"
#include <ace/streams.h>
#include <orbsvcs/Time_Utilities.h>#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "HelloMsgTypeSupportImpl.h"/***************************************************************** main()** Perform OpenDDS setup activities:*   - create a Domain Participant*   - create a Publisher*   - register the StringMsg data type*   - create a Topic*   - create a DataWriter * Write data****************************************************************/int main(int argc, char * argv[])
{DDS::DomainParticipant  * domain;DDS::Publisher          * publisher;DDS::Topic              * topic;DDS::DataWriter         * dw;Hello::StringMsg          stringMsg;DDS::ReturnCode_t       retval;DDS::DomainParticipantFactory *dpf = TheParticipantFactoryWithArgs(argc, argv);
if ( dpf == NULL )
{
printf("ERROR initializing domainParticipantFactory.\n");
return -1;
}    /* create a DomainParticipant */domain = dpf->create_participant( 2, PARTICIPANT_QOS_DEFAULT, NULL, 0 );if ( domain == NULL ){printf("ERROR creating domain participant.\n");return -1;}/* create a Publisher */publisher = domain->create_publisher(PUBLISHER_QOS_DEFAULT, NULL, 0 );if ( publisher == NULL ){printf("ERROR creating publisher.\n");return -1;}/* Register the data type with the OpenDDS middleware. * This is required before creating a Topic with* this data type. */Hello::StringMsgTypeSupport *stringMsgTS = new Hello::StringMsgTypeSupportImpl();;retval = stringMsgTS->register_type( domain, "StringMsg" );if (retval != DDS::RETCODE_OK){printf("ERROR registering type: %s\n", "DDS_error(retval)");return -1;}/* Create a DDS Topic with the StringMsg data type. */topic = domain->create_topic("helloTopic", "StringMsg", TOPIC_QOS_DEFAULT, NULL, 0 );if ( topic == NULL ){printf("ERROR creating topic.\n");return -1;}/* Create a DataWriter on the hello topic, with* default QoS settings and no listeners.*/dw = publisher->create_datawriter( topic, DATAWRITER_QOS_DEFAULT, NULL, 0 );if (dw == NULL){printf("ERROR creating data writer\n");return -1;}/* Initialize the data to send.  The StringMsg data type* has just one string member.* Note: Alwyas initialize a string member with* allocated memory -- the destructor will free * all string members.  */stringMsg.msg = new char[1024];strcpy((char*)stringMsg.msg.in(), "Hello World from C++!");int counter = 1;Hello::StringMsgDataWriter* sm_dw = Hello::StringMsgDataWriter::_narrow(dw);while ( 1 ){sprintf((char*)stringMsg.msg.in(), "Hello World from OpenDDS C++! index=%d", counter);DDS::ReturnCode_t ret = sm_dw->write ( stringMsg, DDS::HANDLE_NIL ); printf("OpenDDS wrote a sample, index=%d\n", counter);fflush(stdout);if ( ret != DDS::RETCODE_OK)
{printf("ERROR writing sample\n");return -1;
}
#ifdef _WIN32Sleep(1000);
#elsesleep(1);
#endifcounter++;}/* Cleanup */retval = domain -> delete_contained_entities();if ( retval != DDS::RETCODE_OK )printf("ERROR (%s): Unable to cleanup DDS entities\n","DDS_error(retval)");dpf->delete_participant(domain);
TheServiceParticipant->shutdown();return 0;
}

HelloMsgSub.cpp

/******************************************************************  file:  HelloMsgSub.cpp*  desc:  Provides a simple C++ 'Hello World' DDS subscriber.*         This subscribing application will receive data*         from the example 'hello world' publishing *         application (hello_pub).*  ****************************************************************/
#include <dds/DCPS/Service_Participant.h>
#include <dds/DCPS/Marked_Default_Qos.h>
#include <dds/DCPS/PublisherImpl.h>
#include <ace/streams.h>
#include <orbsvcs/Time_Utilities.h>#include "dds/DCPS/StaticIncludes.h"#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "HelloMsgTypeSupportImpl.h"#ifdef _WIN32
#  define SLEEP(a)    Sleep(a*1000)
#else
#  define SLEEP(a)    sleep(a);
#endifint all_done = 0;/***************************************************************** Construct a DataReaderListener and override the * on_data_available() method with our own.  All other* listener methods will be default (no-op) functions.****************************************************************/
class SubListener : public DDS::DataReaderListener
{
public:void on_data_available( DDS::DataReader * dr );void on_requested_deadline_missed (DDS::DataReader_ptr reader,const DDS::RequestedDeadlineMissedStatus & status);void on_requested_incompatible_qos (DDS::DataReader_ptr reader,const DDS::RequestedIncompatibleQosStatus & status);void on_liveliness_changed (DDS::DataReader_ptr reader,const DDS::LivelinessChangedStatus & status);virtual void on_subscription_matched (DDS::DataReader_ptr reader,const DDS::SubscriptionMatchedStatus & status);void on_sample_rejected(DDS::DataReader_ptr reader,const DDS::SampleRejectedStatus& status);void on_sample_lost(DDS::DataReader_ptr reader,const DDS::SampleLostStatus& status);
};/***************************************************************** DataReader Listener Method: on_data_avail()** This listener method is called when data is available to* be read on this DataReader.****************************************************************/
void SubListener::on_data_available( DDS::DataReader * dr)
{Hello::StringMsgSeq   samples;DDS::SampleInfoSeq    samples_info;DDS::ReturnCode_t      retval;DDS::SampleStateMask   ss = DDS::ANY_SAMPLE_STATE;DDS::ViewStateMask     vs = DDS::ANY_VIEW_STATE;DDS::InstanceStateMask is = DDS::ANY_INSTANCE_STATE;/* Convert to our type-specific DataReader */Hello::StringMsgDataReader* reader = Hello::StringMsgDataReader::_narrow( dr );/* Take any and all available samples.  The take() operation* will remove the samples from the DataReader so they* won't be available on subsequent read() or take() calls.*/retval = reader->take( samples, samples_info,
DDS::LENGTH_UNLIMITED,
ss,
vs,
is );if ( retval == DDS::RETCODE_OK ){/* iterrate through the samples */
for ( unsigned int i = 0;i < samples.length(); i++)
{/* If this sample does not contain valid data,* it is a dispose or other non-data command,* and, accessing any member from this sample * would be invalid.*/if ( samples_info[i].valid_data)printf("OpenDDS received a sample, No=%d/%d, [%s]\n", i, samples.length(), samples[i].msg.in());
}fflush(stdout);/* read() and take() always "loan" the data, we need to* return it so OpenDDS can release resources associated* with it.  */reader->return_loan( samples, samples_info );}else{printf("ERROR (%s) taking samples from DataReader\n","DDS_error(retval)");}
}void SubListener::on_requested_deadline_missed (
DDS::DataReader_ptr reader,
const DDS::RequestedDeadlineMissedStatus & status)
{printf("ERROR (%s) on_requested_deadline_missed\n","DDS_error(retval)");
}void SubListener::on_requested_incompatible_qos (
DDS::DataReader_ptr reader,
const DDS::RequestedIncompatibleQosStatus & status)
{
printf("ERROR (%s) on_requested_incompatible_qos\n",
"DDS_error(retval)");
}void SubListener::on_liveliness_changed (
DDS::DataReader_ptr reader,
const DDS::LivelinessChangedStatus & status)
{
printf("ERROR (%s) on_liveliness_changed\n",
"DDS_error(retval)");
}void SubListener::on_subscription_matched (
DDS::DataReader_ptr reader,
const DDS::SubscriptionMatchedStatus & status
)
{
printf("ERROR (%s) on_subscription_matched\n",
"DDS_error(retval)");
}void SubListener::on_sample_rejected(
DDS::DataReader_ptr reader,
const DDS::SampleRejectedStatus& status
)
{
printf("ERROR (%s) on_sample_rejected\n",
"DDS_error(retval)");
}void SubListener::on_sample_lost(
DDS::DataReader_ptr reader,
const DDS::SampleLostStatus& status
)
{
printf("ERROR (%s) on_sample_lost\n",
"DDS_error(retval)");
}/***************************************************************** main()** Perform OpenDDS setup activities:*   - create a Domain Participant*   - create a Subscriber*   - register the StringMsg data type*   - create a Topic*   - create a DataReader and attach the listener created above* And wait for data****************************************************************/#if defined(__vxworks) && !defined(__RTP__)
int hello_sub(char * args)
#else
int main(int argc, char * argv[])
#endif
{DDS::DomainParticipant  *  domain;DDS::Subscriber         *  subscriber;DDS::Topic              *  topic;DDS::DataReader         *  dr;SubListener   drListener;DDS::ReturnCode_t          retval;/* Get an instance of the DDS DomainPartiticpantFactory -- * we will use this to create a DomainParticipant.*/DDS::DomainParticipantFactory *dpf = TheParticipantFactoryWithArgs(argc, argv);
if ( dpf == NULL )
{
printf("ERROR initializing domainParticipantFactory.\n");
return -1;
}     /* create a DomainParticipant */domain = dpf->create_participant( 2, PARTICIPANT_QOS_DEFAULT, NULL, 0 );if ( domain == NULL ){printf("ERROR creating domain participant.\n");return -1;}/* create a Subscriber */subscriber = domain->create_subscriber(SUBSCRIBER_QOS_DEFAULT,
NULL,
0 );if ( subscriber == NULL ){printf("ERROR creating subscriber\n");return -1;}/* Register the data type with the OpenDDS middleware. * This is required before creating a Topic with* this data type. */Hello::StringMsgTypeSupport *stringMsgTS = new Hello::StringMsgTypeSupportImpl();;retval = stringMsgTS->register_type( domain, "StringMsg" );if (retval != DDS::RETCODE_OK){printf("ERROR registering type: %s\n", "DDS_error(retval)");return -1;}/* create a DDS Topic with the StringMsg data type. */topic = domain->create_topic( "helloTopic",
"StringMsg",
TOPIC_QOS_DEFAULT,
NULL,
0 );if ( ! topic ){printf("ERROR creating topic\n");return -1;}/* create a DDS_DataReader on the hello topic (notice* the TopicDescription is used) with default QoS settings, * and attach our listener with our on_data_available method.*/dr = subscriber->create_datareader( (DDS::TopicDescription*)topic, DATAREADER_QOS_DEFAULT,&drListener, DDS::DATA_AVAILABLE_STATUS );if ( ! dr ){printf("ERROR creating data reader\n");return -1;}/* Wait forever.  When data arrives at our DataReader, * our dr_on_data_avilalbe method will be invoked.*/while ( !all_done )SLEEP(30);/* Cleanup */retval = domain -> delete_contained_entities();if ( retval != DDS::RETCODE_OK )printf("ERROR (%s): Unable to cleanup DDS entities\n","DDS_error(retval)");dpf->delete_participant(domain);
TheServiceParticipant->shutdown();return 0;
}

步骤六、编译工程

打开HelloMsg.sln,产生动态库HelloMsg_Common.dll(.lib)和发布订阅程序HelloMsgPub.exe和HelloMsgSub.exe

步骤七、运行发布订阅程序

HelloMsgPub -ORBDebugLevel 0 -DCPSDebugLevel 0 -DCPSTransportDebugLevel 0 -DCPSConfigFile ../../etc/dds_udp_conf.ini -ORBLogFile publisher.log
OpenDDS wrote a sample, index=1
OpenDDS wrote a sample, index=2
OpenDDS wrote a sample, index=3
OpenDDS wrote a sample, index=4
OpenDDS wrote a sample, index=5
OpenDDS wrote a sample, index=6
OpenDDS wrote a sample, index=7
OpenDDS wrote a sample, index=8
OpenDDS wrote a sample, index=9
OpenDDS wrote a sample, index=10
HelloMsgSub -ORBDebugLevel 0 -DCPSDebugLevel 0 -DCPSTransportDebugLevel 0 -DCPSConfigFile ../../etc/dds_udp_conf.ini -ORBLogFile subscriber.log

OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=1]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=2]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=3]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=4]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=5]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=6]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=7]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=8]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=9]
OpenDDS received a sample, No=0/1, [Hello World from OpenDDS C++! index=10]

基于OpenDDS开发发布订阅HelloMsg程序的过程(Windows)相关推荐

  1. 基于云开发的微信小程序:个人相册ByUestcXiye

    基于云开发的微信小程序:个人相册ByUestcXiye 作业要求 第一次作业 第二次作业 结课作业 小程序开发入门 开发前的准备 注册微信小程序 新建一个模板小程序 开通云开发服务 第一次作业 参考资 ...

  2. 基于云开发的微信小程序实战教程(二)

    基于云开发的微信小程序实战教程(二) 上篇文章中,简单介绍了下小程序云开发的概念,还有开发工具的安装和配置,云开发环境已经搭建完毕. 本章主要内容:微信开发者工具如何使用,小程序云开发的基础目录结构 ...

  3. vue.js反编译_基于electron-vue开发的微信小程序反编译客户端

    开源一个小程序反编译客户端 咨询小程序反编译的同学比较多,虽然有开源库但是还是有同学不清楚如何去操作,所以索性做了一个客户端方便进行小程序的反编译 # 技术选型 网上已经有大佬实现了C#版的反编译工具 ...

  4. 完整的OpenDDS的发布订阅编写及源码(Windows)

    一个完整的OpenDDS的发布订阅编写及源码,包括SimuMsg.idl.SimuMsg.mwc和SimuMsg.mpc,SimuMsgCommon_Export.h.publisher.cpp.su ...

  5. 基于Uniapp开发的MIPCMS小程序

    基于Uniapp开发的MIPCMS小程序 介绍 很早就有想法把mipcms官方的小程序改了,结果一直拖到现在.最近有了一点空闲时间,简单改造下mipcms小程序. 软件架构 本软件后台采用mipcms ...

  6. 基于JavaSwing开发3D立体字制作程序 课程设计 大作业

    基于JavaSwing开发3D立体字制作程序:   (大作业) 开发环境: Windows操作系统 开发工具: Eclipse+Jdk 运行效果图: 基于JavaSwing开发3D立体字制作程序:  ...

  7. 基于云开发的微信小程序实战教程(一)

    基于云开发的微信小程序实战教程(一) 最近刚开发了款小程序,在开发过程中发现,基于云开发的教程资源不是很多,而且很不详细.所以边实战边总结了下云开发的简单教程,希望对你有所帮助. 本章主要内容:什么是 ...

  8. Eclipse中使用Hadoop集群模式开发配置及简单程序示例(Windows下)

    Hadoop入门配置系列博客目录一览 1. Eclipse中使用Hadoop伪分布模式开发配置及简单程序示例(Linux下) 2. 使用Hadoop命令行执行jar包详解(生成jar.将文件上传到df ...

  9. 基于云开发创建(小程序云商城,基本页面的创建及动态代码的编写)

    CSDN话题挑战赛第2期 参赛话题:万家争鸣的云计算修罗场 在这个专属于"云"的时代,各位云端弄潮儿们,请分享出你的云计算学习历程吧! 你可以从以下几个方面着手(不强制),或者根据 ...

最新文章

  1. 吴裕雄 10-MySQL插入数据
  2. 青春可长可短, 就看自己如何度过(亦或者如白驹过隙, 稍纵即逝 正所谓且行且珍惜)...
  3. jvm系列(九):如何优化Java GC
  4. 【qduoj - 1011】数组中出现最多的元素(巧妙方法 或 排序 或 map)
  5. redis内存模型及应用解读
  6. 初次使用Atlas JavaScript (Part 3 - 实现自己的应用)
  7. Centos7开放及查看端口
  8. sql server 群集_SQL Server 2014 –安装群集实例–分步(1/3)
  9. js高程笔记1-3章
  10. 开源大数据:openLookeng 虚拟化引擎
  11. FastDFS搭建文件服务器
  12. LINUX 内核调试基础+编程基础
  13. 渝粤题库 陕西师范大学 《教育科学研究方法》作业
  14. 【密码学原理与实践】(五)希尔密码
  15. 职场达人教你如何做高效工作汇报!
  16. bootstrap-selectpicker
  17. 计算机网络:网络传输介质
  18. oreo另一个意思_孑孓、仄亾、片爿…看起来天生一对的字,意思竟然大不同
  19. PCIe系列专题之三:3.0 数据链路层概述
  20. 树莓派lnmp安装mysql_在树莓派上搭建LNMP环境

热门文章

  1. java细粒度锁_Java细粒度锁实现的3种方式
  2. alert 回调_JavaScript中到底什么时候回调函数Callback
  3. java年利润编程题_[编程入门]利润计算-题解(Java代码)
  4. html table vtop,PART2HTML语言.doc
  5. leetcode167. 两数之和 II - 并没有那么easy的easy题
  6. C++(STL):14--- forward_list比list更高效的容器
  7. 大数据学习(09)--spark学习
  8. 两条边延长角会有什么变化_叶片锁是什么样的 叶片锁使用方法【详解】
  9. linux加密框架 crypto 算法管理 - 创建哈希算法实例
  10. 英语口语 week11 Friday