You are here: Capabilities and Performance > Compact, Type-Safe Data: Programming with DDS Data Types > Using Built-in DDS Types

Compact, Type-Safe Data: Programming with DDS Data Types

How data is stored or laid out in memory can vary from language to language, compiler to compiler, operating system to operating system, and processor to processor. This combination of language/compiler/operating system/processor is called a platform. Any modern middleware must be able to take data from one specific platform (say C/gcc 3.2.2/Solaris/Sparc) and transparently deliver it to another (for example, Java/JDK 1.6/Windows/Pentium). This process is commonly called serialization/deserialization or marshalling/demarshalling. Messaging products have typically taken one of two approaches to this problem:

The “do nothing” approach is lightweight on its surface but forces you, the user of the middleware API, to consider all data encoding, alignment, and padding issues. The “send everything” alternative results in large amounts of redundant information being sent with every packet, impacting performance.

Figure 1 Self-Describing Messages vs. Type Definitions

Connext DDS exchanges data type definitions, such as field names and types, once at application start-up time. This increases performance and reduces bandwidth consumption compared to the conventional approach, in which each message is self-describing and thus includes a substantial amount of meta-data along with the actual data.

Connext DDS takes an intermediate approach. Just as objects in your application program belong to some data type, DDS data samples sent on the same Topic share a DDS data type. This DDS type defines the fields that exist in the DDS data samples and what their constituent types are; users in the aerospace and defense industries will recognize such type definitions as a form of Interface Definition Document (IDD). Connext DDS stores and propagates this meta-information separately from the individual DDS data samples, allowing it to propagate DDS samples efficiently while handling byte ordering and alignment issues for you.

Figure 2 Example IDD

This example IDD shows one legacy approach to type definition. RTI supports multiple standard type definition formats that are machine readable as well as human readable.

With RTI, you have a number of choices when it comes to defining and using DDS data types. You can choose one of these options, or you can mix and match them—these approaches interoperate with each other and across programming languages and platforms. So, your options are:

The following sections of this document describe each of these models.

Using Built-in DDS Types

Connext DDS provides a set of standard types that are built into the middleware. These DDS types can be used immediately. The supported built-in DDS types are String, KeyedString, Octets, and KeyedOctets. (On Java and .NET platforms, the latter two types are called Bytes and KeyedBytes, respectively; the names are different but the data is compatible across languages.) String and KeyedStrings can be used to send variable-length strings of single-byte characters. Octets and KeyedOctets can be used to send variable-length arrays of bytes.

These built-in DDS types may be sufficient if your data-type needs are simple. If your data is more complex and highly structured, or you want Connext DDS to examine fields within the data for filtering or other purposes, this option may not be appropriate, and you will need to take additional steps to use compile-time types (see Using DDS Types Defined at Compile Time) or dynamic types (see Running with Dynamic DDS Types).

Using DDS Types Defined at Compile Time

In this section, we define a DDS type at compile time using a language-independent description and RTI Code Generator (rtiddsgen).

RTI Code Generator accepts data-type definitions in a number of formats, such as OMG IDL, XML Schema (XSD), and a DDS-specific format of XML. This makes it easy to integrate Connext DDS with your development processes and IT infrastructure. In this section, we will define DDS types using IDL. (In case you would like to experiment with a different format, rtiddsgen can convert from any supported format to any other: simply pass the arguments -convertToIdl, -convertToXml, -convertToXsd, or -convertToWsdl.)

As described in the Release Notes, some platforms are supported as both a host and a target, while others are only supported as a target. The rtiddsgen tool must be run on a computer that is supported as a host. For target-only platforms, you will need to run rtiddsgen and build the application on a separate host computer.

The following sections will take your through the process of generating example code from your own data type.

Generating Code with RTI Code Generator

Don't worry about how DDS types are defined in detail for now (we cover it in Data Types and DDS Data Samples section of the User's Manual). For this example, just copy and paste the following into a new file, HelloWorld.idl.

const long HELLO_MAX_STRING_SIZE = 256;
struct HelloWorld {
	string<HELLO_MAX_STRING_SIZE> message;
};

Next, we will invoke RTI Code Generator (rtiddsgen), which can be found in the $NDDSHOME/bin directory that should already be on your path, to create definitions of your data type in a target programming language, including logic to serialize and deserialize instances of that type for transmission over the network. Then we will build and run the generated code.

For a complete list of the arguments rtiddsgen understands, and a brief description of each of them, run it with the -help argument. More information about rtiddsgen, including its command-line parameters and the list of files it creates, can be found in the User’s Manual.

Note: Running rtiddsgen on a Red Hat Enterprise Linux 4.0 target platform is not supported because it uses an older JRE. You can, however, run rtiddsgen on a newer Linux platform to generate code that can be used on the Red Hat Enterprise Linux 4.0 target.

Building the Generated Code

You have now defined your data type, generated code for it, and customized that code. It's time to compile the example applications.

Running the Example Applications

Run the example publishing and subscribing applications and see them communicate:

Running with Dynamic DDS Types

Dynamic DDS types are not supported when using Ada Language Support

This method may be appropriate for applications for which the structure (type) of messages changes frequently or for deployed systems in which newer versions of applications need to interoperate with existing applications that cannot be recompiled to incorporate message-type changes.

As your system evolves, you may find that your data types need to change. And unless your system is relatively small, you may not be able to bring it all down at once in order to modify them. Instead, you may need to upgrade your types one component at a time-or even on the fly, without bringing any part of the system down.

While covering dynamic DDS types is outside the scope of this section, you can learn more about the subject in Chapter 3 of the User's Manual. You can also view and run the Hello World example code located in examples/connext_dds/<language>/Hello_dynamic/src.

For the examples in Modern C++, see the Modern C++ API reference, Modules > Programming How-To's > DynamicType and DynamicData Use Cases.

© 2015 RTI