C# 订阅内置主题“;DCPSTopic";在DDS中
我正在尝试创建最简单的C#应用程序,它将允许我获取所选DDS域中当前可用的主题。但我似乎不能让它工作C# 订阅内置主题“;DCPSTopic";在DDS中,c#,data-distribution-service,C#,Data Distribution Service,我正在尝试创建最简单的C#应用程序,它将允许我获取所选DDS域中当前可用的主题。但我似乎不能让它工作 // Create the DDS Domain participant on domain ID 0 DDS.DomainParticipant participant = DDS.DomainParticipantFactory.get_instance().create_participant(
// Create the DDS Domain participant on domain ID 0
DDS.DomainParticipant participant =
DDS.DomainParticipantFactory.get_instance().create_participant(
0,
DDS.DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
null, /* Listener */
DDS.StatusMask.STATUS_MASK_NONE);
DDS.Subscriber sub = participant.get_builtin_subscriber();
DDS.DataReader reader1 = sub.lookup_datareader("DCPSTopic");
DDS.TopicBuiltinTopicDataDataReader builtinReader1 =
(DDS.TopicBuiltinTopicDataDataReader)reader1;
DDS.TopicBuiltinTopicDataSeq topicSeq = new DDS.TopicBuiltinTopicDataSeq(10) ;
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);
builtinReader1.read(topicSeq,
infoSeq,
10,
DDS.SampleStateKind.ANY_SAMPLE_STATE,
DDS.ViewStateKind.ANY_VIEW_STATE,
DDS.InstanceStateKind.ANY_INSTANCE_STATE);
运行上面的代码时,我在最后一行(builtinReader1.read(…)中得到一个“Retcode_NoData”异常,即使发布者和订阅者都在同一个域(域0)中运行和发布。你知道我的代码有什么问题吗
顺便说一下。我使用RTI Connext 5.0实现DDS
问候
John使用RTI Connext,主题内置图片的行为与预期不符。查看以下文件: 注意:
DDS\u主题内置图片数据
内置主题旨在传达
有关已发现主题的信息。本主题的示例不可用
在导线上的单独数据包中传播。而是发送数据
作为其他内置主题所承载信息的一部分
(DDS::PublicationBuiltinTopicData
和
DDS::SubscriptionBuiltPicData
)。因此TopicBuiltPicData
数据读取器将不会接收任何数据
它的基本意思是:由于Connext中实现发现的方式,您将不会在任何TopicBuiltingTopicData
DataReaders中看到任何数据。这是您在代码片段中观察到的内容
幸运的是,仍然可以在总线上获取有关主题的信息。这必须通过PublicationBuiltinTopicData和SubscriptionBuiltinTopicData实现。如果查看的文档,可以看到数据包含字符串字段topic\u name
和type\u name
。此外,您可以获得有关类型结构的信息,但这是更高级的,并且是特定于实现的
如果您计划阅读出版物和订阅内置主题,请提供三条备注。首先,与其像您在
“DCPSTopic”
中那样硬编码内置主题的名称,不如参考相应的TypeSupport属性,如中所示:
reader = sub.lookup_datareader(
DDS.PublicationBuiltinTopicDataTypeSupport.PUBLICATION_TOPIC_NAME);
然后很高兴知道,使用Connext,内置DataReader将不包含任何关于与内置订阅者位于同一DomainParticipant中的发布或订阅的示例。换句话说,您只能看到其他参与者的实体,而不能看到您自己的实体
最后,在处理代码时,我注意到,除非按照如下所示替换序列的构造函数调用,否则样本的读取是不起作用的:
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq();
代替
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);
数据序列也是如此。我不知道这是为什么,但它不应该有任何实际意义。雷尼尔是对的。Connext DDS不直接在
主题内置主题数据中传播主题;相反,它是在出版物BuiltinTopicData
和订阅BuiltinTopicData
中间接实现的。这是DDS规范允许的
本指南中有关于如何使用内置主题的信息。HOWTO包含一些工作示例代码。它是用Java而不是C语言编写的,但应该很容易映射。这里的示例一次读取一个样本,因此不需要处理序列sytax
您必须使用的原因:
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq();
而不是:
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);
是指具有两种不同行为的读取/获取API,这取决于传递的序列是“空”(即具有零分配/最大长度)还是具有分配的长度
如果序列为空(这是使用默认构造函数得到的),则read/take的行为与零拷贝API的行为相同。这意味着序列中的实际元素是从中间件中已经存储的元素中“借用”出来的。因此,必须传入的序列必须是“空”序列,以便中间件知道可以用对内部元素的引用替换内容。访问元素后,必须将“借出的元素”返回给调用DataReader::return\u loan
操作的中间件
如果序列不是空的。然后DDS将假定元素已预分配,并将尝试将数据复制到您传递的元素中。您显示的代码的问题是
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);
只分配序列本身。但不是元素。因此,读取/获取调用在尝试复制时将失败。如果要使用此非零拷贝API,则必须在调用之后对每个元素进行分配/赋值,即:
for (int i=0; i< 10; i++ ) {
infoSeq.set_at(i, new DDS.SampleInfo());
}
for(int i=0;i<10;i++){
infoSeq.set_at(i,新的DDS.SampleInfo());
}
这同样适用于数据序列。
如果您这样做,就不必使用DataReader::return\u loan
操作。但会有额外的副本,因此效率较低
您可以在本HOWTO标题中找到有关如何使用DDS序列的更多信息。它是用C++的例子编写的,但是这些原理适用于所有的语言。
问候,,
杰拉尔多你好,雷尼尔,谢谢你的反馈!我已经实现了你的3个建议,现在也在使用订阅和发布内置主题/datareader。但我的应用程序仍然没有给出任何反馈(除了“Retcode_NoData”例外)。我正在一台笔记本电脑上运行该应用程序,其他DDS应用程序正在运行,所有这些应用程序都在域0上,但它们不会显示在我的应用程序中。对于可能出现的问题,你还有其他建议吗?再次感谢!john在笔记本电脑上运行rtidsspy
工具时,您看到什么了吗?它应该发现总线上的所有DataReader和DataWriter,并打印它们的主题和所有更新(按defult)。如果没有显示结果,那么您的笔记本电脑的设置有问题。如果它确实显示了结果,你能检查一下这个,看看它是否适合你吗?井然有序