基于OpenDDS开发发布订阅HelloMsg程序的过程(Windows)
生活随笔
收集整理的這篇文章主要介紹了
基于OpenDDS开发发布订阅HelloMsg程序的过程(Windows)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于OpenDDS的應用開發,主要分兩個部分的工作:
(1)定義自己的IDL文件,并編譯成消息數據類型通訊動態庫;
(2)分別編寫pub和sub程序,運行
具體步驟,有以下幾個:
下面,展開來看。。。
步驟一、定義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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下字符串操作,Linux Ba
- 下一篇: linux 6.8 安装教程,CentO