I'm trying to write a Generic class for Topics that contains a participant, publisher, subscriber, dr, and dw. I have the same class written and working in C++ as a Template and use code like:
auto dds_return_code = T::TypeSupport::register_type(domain_participant, T::TypeSupport::get_type_name());
and
topic_data_reader_ = T::DataReader::narrow(data_reader_);
what is the cooresponding code in C# generics?
T.TypeSupport is unresolved. I'm missing something key.
related:
what is the C# equivalent of:
typename T::DataWriter * topic_data_writer; // T is a topic
Hi Jay,
Our C++ API generics are not based on C++ templates, but on custom C/C++ generic code instantiated at compile time with define pre-processor statements.
The C# generated code is, in reality, C++/CLI code. I don't think it supports generics the way you may need it for what you're describing. But maybe there are other possible ways, could you share a foo example of the C# code structure you're trying to build?
Thanks,
Juanlu
what i have is a C++ template class that works. It's 'T' is a topic. Using T::TypeSupport, i can create a topic of type T. I am trying to rewrite this class in C# using generics. I understand that the rtiddsgen generated code is different but i'm not sure how. I am not an expert in C# generics. I was hoping I am just missing something there and that someone here has written a similar class, as it seems likely that this is a common approach.
When I try T.TypeSupport in C#, i do not have access in the same way i do in C++ with T::TypeSupport.
I can type up some of the code if needed. The class is obviously not complete and not working, and it is on a different (offline) machine. Before I do that, I'd like to confirm that I am making myself and the problem clear.
http://community.rti.com/kb/how-implement-generic-read-and-write-methods-using-cpp-templates
this doc lead us to the C++ template implementation. Is the same trait support available for C# in the .NET api and generated code?
Hi Jay,
No, I believe those traits are not available in the C# implementation. You may be able to create a generic wrapper class anyway. But beware that C# generics are less powerful and expressive than C++ templates.
I think you could still create a wrapper class that is parameterised with the necessary types, this is, the data type class itself, the type support class and the Reader/Writer classes. Then internally perform creation operations and expose your necessary methods for sending/receiving samples. I'm just drafting here, but:
This is just an idea and I don't know if it serves your purpose, but it's just to show you how to use generics in C#. The constructor is responsible for creating the necessary DDS Entities. The class implements the DDS.DataReaderListener interface, so in the creation method, when calling
create_datareader()
, the class should install itself (this) as the listnerer for_reader
. To register the type before creating the Reader or Writer you would callTTypeSupport.register_type()
. Theon_data_available()
method would need to do something generic with the samples, like put them in a generic collection or so. If you don't want this approach you can expose other types of methods for accessing your data (e.g. expose a method that returns a generic collection of type T).In your application code, and after generating the necessary code with RTI DDS Gen, you should be able to do something like:
I hope this helps clarifying and giving you ideas.
Thanks,
Juanlu
this definitely helps. I'm working on implementing the class now(how you have proposed) and am having trouble using TTypeSupport. I have no access to TTypeSupport.register_type() as you say and i do not know how to gain it.
Hi Jay,
You will need to use generic type constraints like this:
Then you can declare your class like this (I used Shapes as the type) This compiles:
Let me know if this helps you.
Thanks,
Juanlu
that helps a lot. that really shows me the difference between C++ templates and C# generics. now, an easy one. is typeName the same as the "topic" name?
It doesn't have to. The type name is a string that represents the registration name that you want to give to the type. The topic is just a name for a data stream. Like with Shapes Demo, different topics can use the same type name.
Beware that depending on the version of the product you're using, the type name has to be consistent across subsystems in order for them to be compatible. With X-Types, the concept of type name equality is only applies when type coercion is disallowed.
What version of the product are you using?
5.1
That version already incorporates X-Types. So the types have to be assignable in order to be compatible, when type coercion is allowed. Section 7.6.6 in the Core Libraries and Utilities User's Manual explains about type consistency.
Although it's usually a good idea to be consistent with type names, you could use different type names.
so i have this class or couple of classes done except for one thing. i can't figure out how to "narrow" my datareader down to a typesafe version.
TDatareader has no narrow function. i guess that means there is no "narrow" for the readers and writers in .NET as I don't see it in the api docs.
Hi Jay,
No, there is no narrow operation for C# DataWriters or DataReaders. The generated typed DataWriters and DataReaders effectively derive from
DDS::TypedDataWriter
andDDS::TypedDataWriter
, which in turn inherit fromDDS::DataWriter
andDDS::DataReader
.C# generics are inherently type-safe. I think you can safely convert from one to the other inside the wrapping class.
Thanks,
Juanlu
do you see me having to pass in a DataSequence as well?
Hi Jay,
You may have to. But you don't need to. Sequences are usually needed when you're going to perform bulk reads or takes. However, DDS provides APIs for taking a single sample or a single instance (
read_next_sample
,read_next_instance
,take_next_sample
,take_next_instance
). However, if you do need to add the sequence type, you can add aTSeq
parameter to the generic class and you add the constraintTSeq : LoanableSequence<T>
.Hope this helps.
that does help, thanks.
There is no class called TyipedDataReader.
Only founding DataReader<DynamicData> DataReaderSphere in demo on git.
When I use GenCode tool gen c# code, the code got an error:ShapeTypeExtendedDataReader can not find.
How can I use my own type?
I am using C# code of newest.