Enum value name and type from DynamicData

6 posts / 0 new
Last post
Offline
Last seen: 3 years 11 months ago
Joined: 11/22/2020
Posts: 1
Enum value name and type from DynamicData

I have defined an enum MyEnum in my IDL with values One and Two. Then I define a struct MyStruct with a single member myEnum of type MyEnum. So far so good.

Now, in my recorder service plugin I'm looking at MyStruct, but in the shape of a DynamicData. I can get the value of the enum with dynamicData.value(int32_t), but how can I translate that to "One" or "Two"? And how can I work out the name of the type ("MyEnum") for that member of the DynamicType? I'm using the modern C++ API of DDS version 6.0.1.

The RTI Admn Console presents the information I need in the "DDS Data Type" tab, so the information is there somewhere...

Organization:
Howard's picture
Offline
Last seen: 2 days 3 hours ago
Joined: 11/29/2012
Posts: 605

You have to use the DynamicData method get_type() which will return a DDS_TypeCode object.

Then on the TypeCode object, you have to use member_type(i) to get the TypeCode object of the enum member.

Which you can verify by checking if TypeCode.kind is

DDS_TK_ENUM 

enumerated type.

Then on the TypeCode of the enum member, you have to iterate through the members of the enum (which are the enumerations) using member(i) which will return the literal and member_ordinal(i) that will return the enumeration "value" corresponding to the literal.

You'll have to write a lookup method based on the parts above...or keep your own mapping of ordinal values to literals.

Offline
Last seen: 2 years 11 months ago
Joined: 02/08/2021
Posts: 21

I'm having the exact same problem, but I can't follow the advice given here on the modern API.

dds::core::xtypes::DynamicData has no member "get_type", only "type".
https://community.rti.com/static/documentation/connext-dds/current/doc/api/connext_dds/api_cpp2/classdds_1_1core_1_1xtypes_1_1DynamicData.html

From there it seems a dead end. I'm iterating a DynamicData that I don't know what contains like this:


// we are either on an Array, Sequence or Struct.
DynamicData& dynamic_data = ...;

for (uint32_t i = 1; i <= dynamic_data.member_count(); ++i){
   DynamicDataMemberInfo member_info = dynamic_data.member_info(i);
   TypeKind kind = member_info.member_kind();
   ...
   if (kind == TypeKind::ENUMERATION_TYPE) {
     // how to get a dds::core::xtypes::EnumType?
   }

This code came from this example:
https://community.rti.com/kb/dynamic-data-how-access-multi-level-nesting-elements-using-c11

I know that if I cast "dynamic_data.type()" to "StructType", then I can access "member(i)" and then the enum, but then I can't iterate in a generic fashion, as the loop above could be an Array.

How to go?

Offline
Last seen: 1 month 52 min ago
Joined: 04/02/2013
Posts: 196

You need to static_cast it. See https://community.rti.com/static/documentation/connext-dds/6.0.1/doc/api/connext_dds/api_cpp2/classdds_1_1core_1_1xtypes_1_1DynamicType.html#details

Offline
Last seen: 2 years 11 months ago
Joined: 02/08/2021
Posts: 21

The thing is that I didn't found how to get the DynamicType of a DynamicData member directly. DynamicDataMemberInfo doesn't seem to allow it. The only way found is to conditionally handle based on the type of the parent DynamicData like this:

std::optional<dds::core::xtypes::DynamicType> get_member_DynamicType(
dds::core::xtypes::DynamicData& parent,
uint32_t member_idx)
{
using namespace dds::core::xtypes;

DynamicType const& parent_type = parent.type();
TypeKind parent_kind = parent_type.kind();
if (parent_kind == TypeKind::STRUCTURE_TYPE)
{
auto type = static_cast<StructType const&>(parent_type);
Member member = type.member(member_idx);
return {member.type()};
}
else if (parent_kind == TypeKind::ARRAY_TYPE ||
parent_kind == TypeKind::SEQUENCE_TYPE)
{
auto type = static_cast<CollectionType const&>(parent_type);
return {type.content_type()};
}
else
{
return {};
}
}

This requires some ceremony and forces to operate with copies instead of references to be able to handle the error case or to avoid code duplication because some of the objects maybe are not used on the same scope they are created.

On the loop above I already know that I'm inside something iterable (Struct, Union, Sequence, Array...).

Anyways, I solved my problem with the code above, but if there is a more terse way to do the same I'd like to know, because this is going to run live at data rate converting arbitrary DDS messages.

PS: Sorry for the formatting, I didn't find a way to paste code that doesn't involve me manually formatting it, so I went with "Plain Text", which apparently doesn't respect leading spaces at the end.

Offline
Last seen: 3 years 1 month ago
Joined: 07/01/2021
Posts: 3

hi

the typecode of enum was contained two members that named _members and _memberCount._memberCount is completely valid according to my enum item,

but when I want to know each enum item's names and call the _members[I]._name I saw the invalid character like "@E" or any invalid characters.

I need to discover enum items name and anybody can help me ?