python connector get type reference

8 posts / 0 new
Last post
Offline
Last seen: 2 years 4 months ago
Joined: 08/12/2021
Posts: 14
python connector get type reference

I'm trying to find a way to determine the type_ref of an rti.Output object.

The xml file contains the topic name to type relationship.  I'm wondering if the rti.Output object has access to the type name.

Here's an example using the ShapesExample.xml

ShapeExample.xml
<types>
    <struct name="ShapeType">
    ...
</types>

<register_type name=ShapeType" type_ref="ShapeType"/>
<topic name="Square" register_type_ref="ShapeType/>
<data_writer name="MySquareWriter" topic_ref="Square"/>

writer.py
output = connector.get_output("... MySquareWriter")
print(output.name) # prints "MySquareWriter"

Is there any function or attribute that will return the string "ShapeType"?

Thanks!
Bobby

 

Offline
Last seen: 1 year 1 month ago
Joined: 10/22/2018
Posts: 91

Hey Bobby,

Unfortunately that is not possible currently, I have raised CON-242 to track your request.

You can always manually extend the Python Connector API yourself, calling the appropariate Connext DDS Pro C APIs.

We actually do this in the unit tests on an input (we obtain the name of the type being subcribed to by an input), you can check that here.

Sam

 

 

Offline
Last seen: 2 years 4 months ago
Joined: 08/12/2021
Posts: 14

Thanks Sam.  I appreciate you creating a ticket.

I looked at the code snippet you linked to, and it works perfectly on Input objects.  The DDS_TopicDescription_get_type_name is needed for the type.

However, there appears to be no Output object equivalent.  There's a DDS_DataReader_get_topicdescription, but not DDS_DataWriter_get_topicdescription.  I've been fiddling around with some of the API calls, but do you know if it's possible to retrieve a data writer's type?  I'm thinking the DDS_DataWriter_get_topic() might work in some way.

 

Here's how to get the type name if anyone needs it in the future.

RTI Connext C API: DataReaders

get_topic = rti.connector_binding.library.DDS_DataReader_get_topicdescription
get_topic.restype = ctypes.c_void_p
get_topic.argtypes = [ctypes.c_void_p]
topic = get_topic(input.native)

get_type_name = rti.connector_binding.library.DDS_TopicDescription_get_type_name
get_type_name.restype = ctypes.c_char_p
get_type_name.argtypes = [ctypes.c_void_p]
print(rti.fromcstring(get_type_name(topic))) # prints the appropriate type
 
Thanks
Bobby
Offline
Last seen: 1 year 1 month ago
Joined: 10/22/2018
Posts: 91

Hey

As you've seen the related DataWriter function is DDS_DataWriter_get_topic.

This returns a DDS_Topic, which (in the C API) would then need to be converted to a DDS_TopicDescription using DDS_Topic_as_topicdescription.

Unfortunately, we cannot call DDS_Topic_as_topicdescription from Python, since it is implemented as a macro in the C libraries.

One option is to use the DynamicData object (the object that is being written by the output) to obtain the name. This could be done as:

get_type = rti.connector_binding.library.DDS_DynamicData_get_type
get_type.restype = ctypes.c_void_p
get_type.argtypes = [ctypes.c_void_p]
type = get_type(output.instance.native)
get_name = rti.connector_binding.library.DDS_TypeCode_name
get_name.restype = ctypes.c_char_p
get_name.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
print(rti.fromcstring(get_name(type, 0))) # prints the appropriate type

Sam

Offline
Last seen: 2 years 4 months ago
Joined: 08/12/2021
Posts: 14

This works!

Thanks so much
Bobby

Offline
Last seen: 2 years 4 months ago
Joined: 08/12/2021
Posts: 14

Extending this post.  

Is it possible using connector or c api to also get the member type?

types.xml
<module name = "moduleA">
    <module name = "moduleB">
        <struct name= "structC">
            <member name= "memberD" type="nonBasic" nonBasicTypeName= "someName">

If memberD eventually resolves to a basic type of float, is there a way to retrieve that info?  I'm currently parsing through a bunch of xml's to determine the answer, but I'm hoping/suspecting there's a better way.

Note, for strings and bools I think this method is ok.  There's just an issue when trying to determine ints vs floats.

 

I tried this:
type(output.get_dictionary()['memberD']), but if memberD is zero (default), this returns an int, when I know the actual base type should be float.

 

Thanks
Bobby

 

 

 

Offline
Last seen: 1 year 1 month ago
Joined: 10/22/2018
Posts: 91

Hey,

So using only Connector APIs that isn't possible (the general ethos with Connetor is to keep the API as simple as possible).

There are some options:

We have type-agnostic setters and getters, in Connector for Python they are implemented using __getitem__ and __setitem__. See this part of the documentation.

output.instance["my_double"] = 2.14
output.instance["my_string"] = "Hello"
output.instance["my_boolean"] = True

Using these you do not need to specify the type of the member that you are setting. Not sure if that fits your use-case or not.

If, you essentially want to work out the types of the members at runtime you will need to use some of the DynamicData APIs that allow you to inspect a DynamicData object, specifically DDS_DynamicData_get_member_type.
Using this you would have to pass output.instance.native as the self argument, use ctypes to generate a type that could be passed by reference for the type_out argument, pass the name of the member you want to inspect as member_name and pass 0 as member_id.

The most complex part will be getting the type_out argument. We do a similar thing in the binding already that you could use as an example. See _AnyValueKind and how it is pased to the get_any_value method.

Hope that helps.

Offline
Last seen: 2 years 4 months ago
Joined: 08/12/2021
Posts: 14

Thanks Sam, I meant to reply to this email a week ago but it slipped my mind. 

I'll need to do this using the API I think. 

Here's my use case.  I have another program that is passing data into my connector.  The problem is that all the data is passed in as a string.

For example, my external program might have:
Set_ID(12345)

Well, 12345 is passed into my connector program as a string.  My idl to xml file may define this field as an int, or maybe a string in this case.  Either way, I need to do a look up to determine it's base type.  I'm currently parsing my xml files to determine the type, but I'd rather use the API if possible.  I'll give your DDS_DynamicData_get_member_type a shot.

Thanks

Bobby