How to separate DDS types in C++ code (generated from IDL)

2 posts / 0 new
Last post
Offline
Last seen: 2 years 7 months ago
Joined: 07/01/2013
Posts: 4
How to separate DDS types in C++ code (generated from IDL)

Hi, 

 Assume that I have created my IDL struct  as below:

struct alphaDDS{

  string name;

  long val;

}

When we generate C++ code, it generates code as below:

class alphaDDS

{

DDS_Char* name;

DDS_Long val;

}

 

Suppose if I have below c++ structure in my application;

class alpha

{

  char* name;

  long val;

}

 alphaDDS class has DDStypes equivalent to builtin types. But alpha uses built-in types.
Can I copy content of alphaDDS object to alpha object?
Is there any is easy way of copying IDL_generated C++ object to pure C++ object?
Why I had to create a class that has built-in types? The reason is that I do not want to use alphaDDS class in my application, as I do not want to propagate DDStype into my applicaion.
My question is about: How can I copy the data( which is received by RTI subscriber) to plain C++ object(which will have same members but all are of built-in type instead of DDS type).
 
Thank you,
Gerardo Pardo's picture
Offline
Last seen: 2 months 1 week ago
Joined: 06/02/2010
Posts: 589

Hi,

I understand that there are cases where propagating the "DDS types" and headers into applications that have nothign to do with DDS is undesirable. This is possible. The approach is described in the section titled Using Generated Types Without RTI Connext (Standalone) in the rtiddsgen manual page.

The fundamental issue is that the C and C++ language do not specify the size of integer types. So you do not know if a C/C++ long will be implememted by the compiler as a 32, 64 (or 16) bit quatity.  Granted most platforms today use 32 bits for "long" but unfortnately one cannot rely on this for portable code. 

This difference does not just affect the ability to copy/cast types on a given platform. But also the ability to communicate. Say you defined your IDL as:

 struct alphaDDS {
     string name;
     long value;  
 };  

This mean that on the wire alphaDDS.value will be a 32-bit signed integer. If you where to map this to:

class alphaDDS {
     char *name;
     long value;  
 };  

Then if your platform represented long using 64 bits you would be thinking you can send any "long" your platform supports but in relity the wire can only carry 32 bits so at best you would be truncating some values. Moreover if your platform represented long using 16 bits then you would not be able to receive the 32-bit integers others write.

This basically what DDS_Long and other such typedefs give you...  These types are defined properly on all platforms to match the bit-representations specifid by the IDL standard types so they will work on all platforms.

Normally these defines are intermixed with the definition of other DDS types. But to support the scenario where teh data-types are used in applications that do not need to include any of the other DDS types we distribute a file called ndds_standalone_type.h under the ${NDDSHOME}/resource/rtiddsgen/standalone/include directory.

The ndds_standalone_type.h  just tyedefs the DDS_Long types and such to the appropriate platform types so you can use the native types instead of the DDS types. 

However the header file generated by rtiddsgen still contains the "DDS_*" typenames, whuch are then typedef to plain C/C++ types. So if you really do not want to see the "DDS_*" names at all you would need to edit this file. If you do that I would recommend you use the portable type definitions in C99 <stdint.h> i.e. things like int32_t or else you must be very sure of the bit representation of the integer types in all platforms you use.

Gerado