OpenDDS - 从单个 IDL 结构创建多个主题

Posted

技术标签:

【中文标题】OpenDDS - 从单个 IDL 结构创建多个主题【英文标题】:OpenDDS - Create multiple topics from single IDL structure 【发布时间】:2017-09-11 07:32:31 【问题描述】:

在我与OpenDDS 的练习中,我想从一个 IDL 结构创建多个主题,这可能吗?否则请告诉我该怎么做。

我是按照下面的方法做的,如果不是正确的方法,请纠正我。 我使用的示例可在OpenDDS-3.12/examples/DCPS/IntroductionToOpenDDS

IDL如下,

StockQuoter.idl
---------------
module StockQuoter

#pragma DCPS_DATA_TYPE "StockQuoter::Quote"
#pragma DCPS_DATA_KEY "StockQuoter::Quote ticker"

  struct Quote 
    string ticker;
    string exchange;
    string full_name;
    double value;
    string data;
    TimeBase::TimeT timestamp;
  ;

publisher.cpp


  // Create TOPICS and TYPES Vector
  std::stringstream ss;
  for(unsigned int idx = 0; idx < 100; ++idx)
  
      ss << (idx+1);
      TOPICS.push_back("TOPIC" + std::string(ss.str()));
      TYPES.push_back("TYPE" + std::string(ss.str()));
      ss.clear();
      ss.str(std::string());
  

     // Register
    for( unsigned int idx = 0; idx < 100; ++idx )
    
        vec_quote_servent.push_back(new StockQuoter::QuoteTypeSupportImpl());
        if (DDS::RETCODE_OK != vec_quote_servent[idx]->register_type(participant.in (), TYPES[idx].c_str()))
        
          cerr << "register_type for " << TYPES[idx] << " failed." << endl;
          ACE_OS::exit(1);
        
    

    // Create a topics
    for( unsigned int idx = 0; idx < 100; ++idx )
    
         vec_quote_topic.push_back(   participant->create_topic (TOPICS[idx].c_str(),
                                      TYPES[idx].c_str(),
                                      default_topic_qos,
                                      DDS::TopicListener::_nil(),
                                      ::OpenDDS::DCPS::DEFAULT_STATUS_MASK));

         if (CORBA::is_nil (vec_quote_topic[idx].in ())) 
             cerr << "create_topic for " << TOPICS[idx] << " failed." << endl;
             ACE_OS::exit(1);
        
     

    // Create DataWriters
    for( unsigned int idx = 0; idx < 100; ++idx )
    
         vec_quote_base_dw.push_back( pub->create_datawriter(vec_quote_topic[idx].in (),
                                      dw_default_qos,
                                      DDS::DataWriterListener::_nil(),
                                      ::OpenDDS::DCPS::DEFAULT_STATUS_MASK) );

        if (CORBA::is_nil (vec_quote_base_dw[idx].in ())) 
           cerr << "create_datawriter for " << TOPICS[idx] << " failed." << endl;
           ACE_OS::exit(1);
        

        vec_quote_dw.push_back( StockQuoter::QuoteDataWriter::_narrow(vec_quote_base_dw[idx].in()) );
        if (CORBA::is_nil (vec_quote_dw[idx].in ())) 
          cerr << TOPICS[idx] << " could not be narrowed"<< endl;
          ACE_OS::exit(1);
        
    

    // Create handle
    for( unsigned int idx = 0; idx < 100 ; ++idx )
    
        
            StockQuoter::Quote topic2;
            topic2.ticker = CORBA::string_dup(TOPICS[idx].c_str());
            vec_topic_handle.push_back(vec_quote_dw[idx]->register_instance(topic2));
        
    

      // Publish data
      StockQuoter::Quote vec_quote;
      vec_quote.exchange = STOCK_EXCHANGE_NAME;
      vec_quote.ticker = CORBA::string_dup("VEC_TOPIC");
      vec_quote.full_name = CORBA::string_dup("TOPIC Receipts");
      vec_quote.value = 1600.0 + 10.0*i;
      vec_quote.timestamp = get_timestamp();

      for(unsigned int idx = 0; idx < 100; ++idx )
      
          vec_quote.value += idx + 10;
          cout << "Publishing " << TOPICS[idx] << " : " << vec_quote.value <<endl;
          ret = vec_quote_dw[idx]->write(vec_quote, vec_topic_handle[idx]);
          if (ret != DDS::RETCODE_OK) 
             ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: TOPIC2 write returned %d.\n"), ret));
          
      

【问题讨论】:

【参考方案1】:

a,现在我明白你想问的重点了。您可以在每个主题一个文件中定义不同的主题类型,也可以在一个文件中定义所有主题类型。如果您在 IDL 文件中定义了多个主题类型,则会为每个文件生成类型支持。让我用您使用的相同示例更准确地描述这一点。 IntroductionToOpenDDS 示例的 IDL 文件如下所示:

#include "orbsvcs/TimeBase.idl"

module StockQuoter

#pragma DCPS_DATA_TYPE "StockQuoter::Quote"
#pragma DCPS_DATA_KEY "StockQuoter::Quote ticker"

struct Quote 
    string ticker;
    string exchange;
    string full_name;
    double value;
    TimeBase::TimeT timestamp;
;

#pragma DCPS_DATA_TYPE "StockQuoter::ExchangeEvent"
#pragma DCPS_DATA_KEY "StockQuoter::ExchangeEvent exchange"

enum ExchangeEventType  TRADING_OPENED,
                       TRADING_CLOSED,
                       TRADING_SUSPENDED,
                       TRADING_RESUMED ;
struct ExchangeEvent 
    string exchange;
    ExchangeEventType event;
    TimeBase::TimeT timestamp;
;
;

如您所见,定义了两种类型:QuoteExchangeEvent。编译此 IDL 文件时,将生成对 QuoteExchangeEvent 的类型支持。 您已经使用了类型支持来使用此行 (QuoteTypeSupportImpl):

    vec_quote_servent.push_back(new StockQuoter::QuoteTypeSupportImpl());

ExchangeEvent 生成相同的类型支持,您会发现一个名为StockQuoter::ExchangeEvent 的类型支持带有 StockQuoter::ExchangeEventTypeSupportImpl() 方法。只需使用它来创建ExchangeEvent 类型的主题。

我希望这会有所帮助。如果需要更多详细信息,请随时询问。

【讨论】:

【参考方案2】:

您可以从单个 IDL 文件中创建任意数量的主题。你已经用这条线做了:

participant->create_topic (TOPICS[idx].c_str(),
                           TYPES[idx].c_str(),
                           default_topic_qos,
                           DDS::TopicListener::_nil(),
                           ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

但是,您创建的每个主题都具有相同的类型。如果需要,您还可以为主题创建不同的类型。

【讨论】:

感谢您为它提供了一些启发。非常感谢来自同一代码的一些示例来演示“如果需要,您还可以为主题创建不同类型”这一点。

以上是关于OpenDDS - 从单个 IDL 结构创建多个主题的主要内容,如果未能解决你的问题,请参考以下文章

opendds TAO_IDL_GEN、OpenDDS_XML_QOS_XSC_Generation 和其他跳过的包

OpenDDS IDL 序列类型

tao_idl -Gstl 不映射 std::string

共享内存主/从进程访问单个串口

从单个商店动态创建多个 Sencha ExtJS 商店

使用大量 IDL 接口管理 COM 类型库中的定义