I'm still trying to grasp my head around how the C# connector works.
I made a custom type in the XML, tried to make a subscriber of that type, and the C# app just crashes at the line where DomainParticipant.CreateTopic is called.
I just don't understnad why.
---> Omg.Dds.Core.DdsException: DDS operation failed:
at Rti.Dds.NativeInterface.Helpers.ReturnCode.CheckResult(IntPtr result)
at Rti.Dds.NativeInterface.Core.NativeQosProvider.GetTypeCodeFromTypeLibrary(String libraryName, String typeName)
at Rti.Dds.Core.QosProvider.GetType(String libraryName, String typeName)
at Rti.Dds.Core.QosProvider.GetType(String typeName)
at MyExample.MyExampleSubscribe.Main(Int32 domainId, Int32 sampleCount) in H:\Storage\Vcom3D\AMM\Projects\MyExample\MyExampleSubscribe
r\MyExampleSubscriber.cs:line 52
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptio
ns)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo cul
ture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseErrorReporting>b__20_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass15_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass24_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__21_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseDebugDirective>b__11_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass6_0.<<ConfigureConsole>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseExceptionHandler>b__0>d.MoveNext()
namespace MyExample {
public static class MyExampleSubscribe {
private static int ProcessData(DataReader<DynamicData> reader) {
int samplesRead = 0;
using var samples = reader.Take();
foreach (var sample in samples.ValidData) {
Console.WriteLine($"Received: {sample}");
samplesRead++;
}
return samplesRead;
}
public static void Main (int domainId = 0, int sampleCount = 10) {
// A DomainParticipant allows an application to begin communicating in
// a DDS domain. Typically there is one DomainParticipant per application.
// DomainParticipant QoS is configured in USER_QOS_PROFILES.xml
//
// A participant needs to be Disposed to release middleware resources.
// The 'using' keyword indicates that it will be Disposed when this
// scope ends.
using DomainParticipant participant = DomainParticipantFactory.Instance
.CreateParticipant(domainId);
// A Topic has a name and a datatype. Create dynamically-typed
// Topic named "MyExample Topic" with the type definition of
// "MyExample" in MyExample.xml. To get the type we use a QosProvider
var provider = new QosProvider("MyExample.xml");
Topic<DynamicData> topic = participant.CreateTopic(
"SuperData",
provider.GetType("SuperData")
);
Subscriber subscriber = participant.CreateSubscriber();
DataReader<DynamicData> reader = subscriber.CreateDataReader(topic);
var statusCondition = reader.StatusCondition;
statusCondition.EnabledStatuses = StatusMask.DataAvailable;
int samplesRead = 0;
statusCondition.Triggered += _ => samplesRead += ProcessData(reader);
var waitset = new WaitSet();
waitset.AttachCondition(statusCondition);
while (samplesRead < sampleCount) {
Console.WriteLine("MyExample subscriber sleeping for 4 sec...");
waitset.Dispatch(Duration.FromSeconds(4));
}
}
}
}
<types>
<!-- Define your types here -->
<struct name="SuperData">
<member name="msg" stringMaxLength="256" type="string" />
</struct>
</types>
It looks like you're not using Connector, but the alpha preview of the Connext DDS C# API. In any case the types file format requires the <dds> tag:
<dds>
<types>
<!-- Define your types here -->
<struct name="SuperData">
<member name="msg" stringMaxLength="256" type="string" />
</struct>
</types>
</dds>
Did you get any additional message in the console?
Tried to again with the example code. This runs with out error
Topic<DynamicData> topic = participant.CreateTopic(
"MyExample",
provider.GetType("MyExample")
);
But this doesn't. I don't understand why even when I change the XML to match.
Topic<DynamicData> topic = participant.CreateTopic(
"MyExample",
provider.GetType("My Example")
);
<types>
<!-- Define your types here -->
<struct name= "My Example">
<member name="msg" stringMaxLength="256" type="string"/>
</struct>
</types>
Yeah, I am including the dds tag. I've just been cutting lines.
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.0.1/rti_dds_profiles.xsd">
<types>
<!-- Define your types here -->
<struct name= "My Example">
<member name="msg" stringMaxLength="256" type="string"/>
</struct>
</types>
</dds>
Is there a difference between Connector and Conmext DDS C# API?
I tried building their github and then was told their github is no longer maintained.
https://github.com/rticommunity/rticonnextdds-connector-cs
Then I was told to use these NuGet packages, so that's what I'm currently on.
https://www.nuget.org/packages/RTI.Connext.Connector/0.3.3-alpha02
https://www.nuget.org/packages/Rti.ConnextDds/0.0.1-alpha09
Now I'm at the point where I don't know what I should be using.
Connector is a simplified API to access the DDS databus and is available in Python and JavaScript: https://community.rti.com/static/documentation/connector/1.0.0/api/python/intro.html
Connector has an experimental C# binding that is no longer maintained.
Connext DDS is the full DDS API, available in C, C++ (traditional and modern), Java, and .NET Framework (Windows only).
A brand new C# Connext DDS API for .NET Core is under development, and you're using an alpha Preview published in Nuget (ttps://www.nuget.org/packages/Rti.ConnextDds/0.0.1-alpha09)