RTI Connext
Core Libraries and Utilities
User’s Manual
Part 2 — Core Concepts
Chapters
Version 5.0
© 2012
All rights reserved.
Printed in U.S.A. First printing.
August 2012.
Trademarks
Copy and Use Restrictions
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form (including electronic, mechanical, photocopy, and facsimile) without the prior written permission of Real- Time Innovations, Inc. The software described in this document is furnished under and subject to the RTI software license agreement. The software may be used or copied only under the terms of the license agreement.
Note: In this section, "the Software" refers to
This product implements the DCPS layer of the Data Distribution Service (DDS) specification version 1.2 and the DDS Interoperability Wire Protocol specification version 2.1, both of which are owned by the Object Management, Inc. Copyright
Portions of this product were developed using ANTLR (www.ANTLR.org). This product includes software developed by the University of California, Berkeley and its contributors.
Portions of this product were developed using AspectJ, which is distributed per the CPL license. AspectJ source code may be obtained from Eclipse. This product includes software developed by the University of California, Berkeley and its contributors.
Portions of this product were developed using MD5 from Aladdin Enterprises.
Portions of this product include software derived from Fnmatch, (c) 1989, 1993, 1994 The Regents of the University of California. All rights reserved. The Regents and contributors provide this software "as is" without warranty.
Portions of this product were developed using EXPAT from Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 2001, 2002 Expat maintainers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Technical Support
232 E. Java Drive
Sunnyvale, CA 94089
Phone: |
(408) |
Email: |
support@rti.com |
Website: |
Contents, Part 2
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
3.2.8.1 |
||
|
|||
|
|||
iii
|
|||
|
|||
|
|||
|
|||
3.4 Creating User Data Types with Extensible Markup Language (XML) |
|||
|
|||
|
|||
|
||
|
||
|
4.1.7.1 Changing the QoS Defaults Used to Create Entities: set_default_*_qos() |
|
|
||
|
||
|
||
4.2.1 QoS Requested vs. Offered |
||
iv
|
||||
|
||||
|
|
|||
|
|
|||
|
||||
|
||||
|
||||
|
4.4.2 Creating and Deleting Listeners |
|||
|
||||
|
||||
|
|
|||
|
||||
|
||||
|
4.6.1 Creating and Deleting WaitSets |
|||
|
||||
|
||||
|
|
|||
|
4.6.4 Processing Triggered |
|||
|
||||
|
||||
|
||||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|
|||
|
|
|||
|
||||
|
||||
|
||||
|
|
|||
|
|
5.1.3.2 Changing QoS Settings After the Topic Has Been Created |
||
|
5.1.4 Copying QoS From a Topic to a DataWriter or DataReader |
|||
|
||||
|
||||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
v
|
|||||
|
|
||||
|
|||||
|
|
||||
|
|
5.4.2 Where Filtering is |
|||
|
|
||||
|
|
||||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|||||
|
|||||
|
|
||||
|
|
vi
|
|||
|
|||
|
|||
|
Getting and Setting the Publisher’s Default QoS Profile and Library |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
6.3.14 Managing Data Instances (Working with Keyed Data Types) |
vii
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
viii
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
Propagating Serialized Keys with |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
ix
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
x
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
xi
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
|
|||
|
|
|
|||
|
|
6.6.5 Creating and Configuring Custom FlowControllers with Property QoS |
|||
|
|
|
|||
|
|
||||
|
|
||||
|
|
6.6.8 Getting/Setting Properties for a Specific FlowController |
|||
|
|
||||
|
|
||||
|
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
|
|||
|
|
||||
|
|
|
7.2.4.1 Configuring QoS Settings when the Subscriber is Created |
||
|
|
|
|||
|
|
|
Getting and Settings the Subscriber’s Default QoS Profile and Library |
||
|
|
|
|||
|
|
|
|||
|
|
||||
|
|
xii
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
7.3.8.1 Configuring QoS Settings when the DataReader is Created |
||
|
7.3.8.2 Changing QoS Settings After DataReader Has Been Created |
||
|
7.3.8.3 Using a Topic’s QoS to Initialize a DataWriter’s QoS |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
read_next_instance_w_condition and take_next_instance_w_condition |
||
|
|||
|
|||
|
xiii
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|
8.2.1.1Getting and Setting the DomainParticipantFactory’s Default QoS Profile and
xiv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Configuring QoS Settings when the DomainParticipant is Created |
||
|
|
Changing QoS Settings After the DomainParticipant Has Been Created |
||
|
|
Getting and Setting the DomainParticipant’s Default QoS Profile and Library 8- |
||
|
|
|
19 |
|
|
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
xv
8.5.3.3Controlling the Reliable Protocol Used by
8.5.4 DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension) |
||
8.5.4.1 Configuring Resource Limits for Asynchronous DataWriters |
||
xvi
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
||||
|
||||
|
||||
|
|||
|
|||
|
|||
|
9.4.2 Using Visual Studio .NET, Visual Studio .NET 2003, or Visual Studio 2005 |
||
|
|||
|
xvii
Chapter 3 Data Types and Data Samples
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 XP/Pentium). This process is commonly called serialization/deserialization, or marshalling/demarshalling.
Messaging products have typically taken one of two approaches to this problem:
1.Do nothing. Messages consist only of opaque streams of bytes. The JMS BytesMessage is an example of this approach.
2.Send everything, every time.
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.
Connext takes an intermediate approach. Just as objects in your application program belong to some data type, data samples sent on the same Connext topic share a data type. This type defines the fields that exist in the data samples and what their constituent types are. The middleware stores and propagates this
To publish and/or subscribe to data with Connext, you will carry out the following steps:
1.Select a type to describe your data.
You have a number of choices. You can choose one of these options, or you can mix and match them.
•Use a
This option may be sufficient if your data typing needs are very simple. If your data is highly structured, or you need to be able to examine fields within that data for filtering or other purposes, this option may not be appropriate. The
•Use the RTI code generator, rtiddsgen, to define a type at
Code generation offers two strong benefits not available with dynamic type definition: (1) it allows you to share type definitions across programming languages, and (2) because the structure of the type is known at compile time, it provides rigorous static type safety.
The code generator accepts input in a number of formats to make it easy to integrate Connext with your development processes and IT infrastructure:
•OMG IDL. This format is a standard component of both the DDS and CORBA specifications. It describes data types with a
•XML schema (XSD), either independent or embedded in a WSDL file. XSD should be the format of choice for those using Connext alongside or connected to a web- services infrastructure. This format is described in Creating User Data Types with XML Schemas (XSD) (Section 3.5).
•XML in a
•Define a type programmatically at run time.
This method may be appropriate for applications with dynamic data description needs: applications for which types change frequently or cannot be known ahead of time. It is described in Defining New Types (Section 3.8.2).
2.Register your type with a logical name.
If you've chosen to use a
This step is described in the Defining New Types (Section 3.8.2).
3.Create a Topic using the type name you previously registered.
If you've chosen to use a
Creating and working with Topics is discussed in Chapter 5: Topics.
4.Create one or more DataWriters to publish your data and one or more DataReaders to subscribe to it.
The concrete types of these objects depend on the concrete data type you've selected, in order to provide you with a measure of type safety.
Creating and working with DataWriters and DataReaders are described in Chapter 6: Sending Data and Chapter 7: Receiving Data, respectively.
Whether publishing or subscribing to data, you will need to know how to create and delete data samples and how to get and set their fields. These tasks are described in Working with Data Samples (Section 3.9).
This chapter describes:
❏Introduction to the Type System (Section 3.1 on Page
❏
❏Creating User Data Types with IDL (Section 3.3 on Page
❏Creating User Data Types with Extensible Markup Language (XML) (Section 3.4 on Page
❏Creating User Data Types with XML Schemas (XSD) (Section 3.5 on Page
❏Using rtiddsgen (Section 3.6 on Page
❏Using Generated Types without Connext (Standalone) (Section 3.7 on Page
❏Interacting Dynamically with User Data Types (Section 3.8 on Page
❏Working with Data Samples (Section 3.9 on Page
3.1Introduction to the Type System
A user data type is any custom type that your application defines for use with Connext. It may be a structure, a union, a value type, an enumeration, or a typedef (or language equivalents).
Your application can have any number of user data types. They can be composed of any of the primitive data types listed below or of other user data types.
Only structures, unions, and value types may be read and written directly by Connext; enums, typedefs, and primitive types must be contained within a structure, union, or value type. In order for a DataReader and DataWriter to communicate with each other, the data types associated with their respective Topic definitions must be identical.
❏octet, char, wchar
❏short, unsigned short
❏long, unsigned long
❏long long, unsigned long long
❏float
❏double, long double
❏boolean
❏enum (with or without explicit values)
❏bounded and unbounded string and wstring
The following
❏module (also called a package or namespace)
❏pointer
❏array of primitive or user type elements
❏bounded/unbounded sequence of
❏typedef
❏bitfield2
❏union
❏struct
❏value type, a complex type that supports inheritance and other
1.Sequences of sequences are not supported directly. To work around this constraint, typedef the inner sequence and form a sequence of that new type.
2.Data types containing bitfield members are not supported by DynamicData.
To use a data type with Connext, you must define that type in a way the middleware understands and then register the type with the middleware. These steps allow Connext to serialize, deserialize, and otherwise operate on specific types. They will be described in detail in the following sections.
3.1.1Sequences
A sequence contains an ordered collection of elements that are all of the same type. The operations supported in the sequence are documented in the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, Sequence Support).
Java sequences implement the java.util.List interface from the standard Collections framework.
C++ users will find sequences conceptually similar to the deque class in the Standard Template Library (STL).
Elements in a sequence are accessed with their index, just like elements in an array. Indices start from zero. Unlike arrays, however, sequences can grow in size. A sequence has two sizes associated with it: a physical size (the "maximum") and a logical size (the "length"). The physical size indicates how many elements are currently allocated by the sequence to hold; the logical size indicates how many valid elements the sequence actually holds. The length can vary from zero up to the maximum. Elements cannot be accessed at indices beyond the current length.
A sequence may be declared as bounded or unbounded. A sequence's "bound" is the maximum number of elements tha tthe sequence can contain at any one time. The bound is very important because it allows Connext to preallocate buffers to hold serialized and deserialized samples of your types; these buffers are used when communicating with other nodes in your distributed system. If a sequence had no bound, Connext would not know how large to allocate its buffers and would therefore have to allocate them on the fly as individual samples were read and
3.1.2Strings and Wide Strings
Connext supports both strings consisting of
Like sequences, strings may be bounded or unbounded. A string's "bound" is its maximum length (not counting the trailing NULL character in C and C++).
3.1.3Introduction to TypeCode
Type
enum TCKind { TK_NULL, TK_SHORT, TK_LONG, TK_USHORT,
TK_ULONG,
TK_FLOAT,
TK_DOUBLE,
TK_BOOLEAN, TK_CHAR, TK_OCTET, TK_STRUCT, TK_UNION, TK_ENUM, TK_STRING, TK_SEQUENCE, TK_ARRAY, TK_ALIAS, TK_LONGLONG, TK_ULONGLONG, TK_LONGDOUBLE, TK_WCHAR, TK_WSTRING, TK_VALUE, TK_SPARSE
}
Type codes unambiguously match type representations and provide a more reliable test than comparing the string type names.
The TypeCode class, modeled after the corresponding CORBA API, provides access to type- code information. For details on the available operations for the TypeCode class, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Type Code Support).
3.1.3.1Sending TypeCodes on the Network
In addition to being used locally, serialized type codes are typically published automatically during discovery as part of the
Note: Type codes are not cached by Connext upon receipt and are therefore not available from the
DataReader's get_matched_publication_data() operation.
If your data type has an especially complex type code, you may need to increase the value of the type_code_max_serialized_length field in the DomainParticipant's
DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension) (Section 8.5.4). Or, to prevent the propagation of type codes altogether, you can set this value to zero (0). Be aware that some features of monitoring tools, as well as some features of the middleware itself (such as ContentFilteredTopics) will not work correctly if you disable TypeCode propagation.
3.2
Connext provides a set of standard types that are built into the middleware. These types can be used immediately; they do not require writing IDL, invoking the rtiddsgen utility (see Section 3.6), or using the dynamic type API (see Section 3.2.8).
The supported
The
❏Registering
❏Creating Topics for
❏Creating ContentFilteredTopics for
❏String
❏KeyedString
❏Octets
❏KeyedOctets
❏Type Codes for
3.2.1Registering
By default, the
3.2.2Creating Topics for
To create a topic for a
Note: In the following examples, you will see the sentinel "<BuiltinType>."
For C and C++: <BuiltinType> = String, KeyedString, Octets or KeyedOctets For Java and .NET1: <BuiltinType> = String, KeyedString, Bytes or KeyedBytes
C API:
const char* DDS_<BuiltinType>TypeSupport_get_type_name();
C++ API with namespace:
const char* DDS::<BuiltinType>TypeSupport::get_type_name();
C++ API without namespace:
const char* DDS<BuiltinType>TypeSupport::get_type_name();
C++/CLI API:
System::String^ DDS:<BuiltinType>TypeSupport::get_type_name();
C# API:
System.String DDS.<BuiltinType>TypeSupport.get_type_name();
1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.
Java API:
String com.rti.dds.type.builtin.<BuiltinType>TypeSupport.get_type_name();
3.2.2.1Topic Creation Examples
For simplicity, error handling is not shown in the following examples.
C Example:
DDS_Topic * topic = NULL;
/* Create a builtin type Topic */
topic = DDS_DomainParticipant_create_topic( participant, "StringTopic",
DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
C++ Example with Namespaces:
using namespace DDS;
...
/* Create a String builtin type Topic */ Topic * topic =
"StringTopic", StringTypeSupport::get_type_name(),
DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
C++/CLI Example:
using namespace DDS;
...
/* Create a builtin type Topic */
Topic^ topic =
"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,
nullptr, StatusMask::STATUS_MASK_NONE);
C# Example:
using namespace DDS;
...
/* Create a builtin type Topic */
Topic topic = participant.create_topic(
"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,
null, StatusMask.STATUS_MASK_NONE);
Java Example:
import com.rti.dds.type.builtin.*;
...
/* Create a builtin type Topic */
Topic topic = participant.create_topic(
"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,
null, StatusKind.STATUS_MASK_NONE);
3.2.3Creating ContentFilteredTopics for
To create a ContentFilteredTopic for a
The field names used in the filter expressions for the
3.2.3.1ContentFilteredTopic Creation Examples
For simplicity, error handling is not shown in the following examples.
C Example:
DDS_Topic * topic = NULL;
DDS_ContentFilteredTopic * contentFilteredTopic = NULL; struct DDS_StringSeq parameters = DDS_SEQUENCE_INITIALIZER;
/* Create a string ContentFilteredTopic */ topic = DDS_DomainParticipant_create_topic(
participant, "StringTopic", DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT,NULL, DDS_STATUS_MASK_NONE);
contentFilteredTopic = DDS_DomainParticipant_create_contentfilteredtopic( participant, "StringContentFilteredTopic",
topic, "value = 'Hello World!'", & parameters);
C++ Example with Namespaces:
using namespace DDS;
...
/* Create a String ContentFilteredTopic */ Topic * topic =
"StringTopic", StringTypeSupport::get_type_name(), TOPIC_QOS_DEFAULT, NULL, STATUS_MASK_NONE);
StringSeq parameters;
ContentFilteredTopic * contentFilteredTopic =
"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);
C++/CLI Example:
using namespace DDS;
...
/* Create a String ContentFilteredTopic */ Topic^ topic =
"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,
nullptr, StatusMask::STATUS_MASK_NONE);
StringSeq^ parameters = gcnew StringSeq();
ContentFilteredTopic^ contentFilteredTopic =
"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);
C# Example:
using namespace DDS;
...
/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(
"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,
null, StatusMask.STATUS_MASK_NONE);
StringSeq parameters = new StringSeq();
ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(
"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);
Java Example:
import com.rti.dds.type.builtin.*;
...
/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(
"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,
null, StatusKind.STATUS_MASK_NONE);
StringSeq parameters = new StringSeq();
ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(
"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);
3.2.4String
The String
3.2.4.1Creating and Deleting Strings
In C and C++, Connext provides a set of operations to create (DDS::String_alloc()), destroy (DDS::String_free()), and clone strings (DDS::String_dup()). Select Modules, DDS API Reference, Infrastructure Module, String support in the API Reference HTML documentation, which is available for all supported programming languages.
1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.
Memory Considerations in Copy Operations:
When the read/take operations that take a sequence of strings as a parameter are used in copy mode, Connext allocates the memory for the string elements in the sequence if they are initialized to NULL.
If the elements are not initialized to NULL, the behavior depends on the language:
•In Java and .NET, the memory associated with the elements is reallocated with every sample, because strings are immutable objects.
•In C and C++, the memory associated with the elements must be large enough to hold the received data. Insufficient memory may result in crashes.
When take_next_sample() and read_next_sample() are called in C and C++, you must make sure that the input string has enough memory to hold the received data. Insufficient memory may result in crashes.
3.2.4.2String DataWriter
The string DataWriter API matches the standard DataWriter API (see Using a
The following examples show how to write simple strings with a string
C Example:
DDS_StringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;
char * str = NULL;
/* Write some data */
retCode = DDS_StringDataWriter_write(
stringWriter, "Hello World!", &DDS_HANDLE_NIL);
str = DDS_String_dup("Hello World!");
retCode = DDS_StringDataWriter_write(stringWriter, str, &DDS_HANDLE_NIL); DDS_String_free(str);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
StringDataWriter * stringWriter = ... ;
/* Write some data */
ReturnCode_t retCode =
retCode =
DDS::String_free(str);
C++/CLI Example:
using namespace System; using namespace DDS;
...
StringDataWriter^ stringWriter = ... ;
/* Write some data */
C# Example:
using System; using DDS;
...
StringDataWriter stringWriter = ... ;
/* Write some data */
stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";
stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);
Java Example:
import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;
...
StringDataWriter stringWriter = ... ;
/* Write some data */
stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";
stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);
3.2.4.3String DataReader
The string DataReader API matches the standard DataReader API (see Using a
The following examples show how to read simple strings with a string
C Example:
struct DDS_StringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_StringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;
int i;
/* Take and print the data */
retCode = DDS_StringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
for (i = 0; i < DDS_StringSeq_get_length(&data_seq); ++i) {
if (DDS_SampleInfoSeq_get_reference(&info_seq,
DDS_StringSeq_get(&data_seq, i));
}
}
/* Return loan */
retCode = DDS_StringDataReader_return_loan(stringReader, &data_seq, &info_seq);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
StringSeq dataSeq;
SampleInfoSeq infoSeq;
StringDataReader * stringReader = ... ;
/* Take a print the data */
ReturnCode_t retCode =
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {
StringTypeSupport::print_data(dataSeq[i]);
}
}
/* Return loan */
retCode =
C++/CLI Example:
using namespace System; using namespace DDS;
...
StringSeq^ dataSeq = gcnew StringSeq(); SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq(); StringDataReader^ stringReader = ... ;
/* Take and print the data */
ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if
}
}
/* Return loan */
C# Example:
using System; using DDS;
...
StringSeq dataSeq = new StringSeq();
SampleInfoSeq infoSeq = new SampleInfoSeq();
StringDataReader stringReader = ... ;
/* Take and print the data */ stringReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {
StringTypeSupport.print_data(dataSeq.get_at(i));
}
}
Java Example:
import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;
...
StringSeq dataSeq = new StringSeq();
SampleInfoSeq infoSeq = new SampleInfoSeq();
StringDataReader stringReader = ... ;
/* Take and print the data */ stringReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) {
if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((String)dataSeq.get(i));
}
}
/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);
3.2.5KeyedString
The Keyed String
C/C++ Representation (without namespaces):
struct DDS_KeyedString { char * key;
char * value;
};
C++/CLI Representation:
namespace DDS {
public ref struct KeyedString: { public:
System::String^ key; System::String^ value;
...
};
};
C# Representation:
namespace DDS {
public class KeyedString { public System.String key; public System.String value;
};
};
Java Representation:
namespace DDS {
public class KeyedString { public System.String key; public System.String value;
};
};
3.2.5.1Creating and Deleting Keyed Strings
Connext provides a set of constructors/destructors to create/destroy Keyed Strings. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module,
If you want to manipulate the memory of the fields 'value' and 'key' in the KeyedString struct in C/C++, use the operations DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(), as described in the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).
3.2.5.2Keyed String DataWriter
The keyed string DataWriter API is extended with the following methods (in addition to the standard methods described in Using a
DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose( const char* key,
const DDS::InstanceHandle_t* instance_handle);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose_w_timestamp( const char* key,
const DDS::InstanceHandle_t* instance_handle, const struct DDS::Time_t* source_timestamp);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::get_key_value( char * key,
const DDS::InstanceHandle_t* handle);
DDS::InstanceHandle_t DDS::KeyedStringDataWriter::lookup_instance(
const char * key);
DDS::InstanceHandle_t DDS::KeyedStringDataWriter::register_instance(
const char* key);
DDS::InstanceHandle_t
DDS_KeyedStringDataWriter::register_instance_w_timestamp(
const char * key,
const struct DDS_Time_t* source_timestamp);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance( const char * key,
const DDS::InstanceHandle_t* handle);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance_w_timestamp(
const char* key,
const DDS::InstanceHandle_t* handle,
const struct DDS::Time_t* source_timestamp);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::write ( const char * key,
const char * str,
const DDS::InstanceHandle_t* handle);
DDS::ReturnCode_t DDS::KeyedStringDataWriter::write_w_timestamp( const char * key,
const char * str,
const DDS::InstanceHandle_t* handle,
const struct DDS::Time_t* source_timestamp);
These operations are introduced to provide maximum flexibility in the format of the input parameters for the write and instance management operations. For additional information and a complete description of the operations, see the API Reference HTML documentation, which is available for all supported programming languages.
The following examples show how to write keyed strings using a keyed string
C Example:
DDS_KeyedStringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;
struct DDS_KeyedString * keyedStr = NULL; char * str = NULL;
/* Write some data using the KeyedString structure */ keyedStr = DDS_KeyedString_new(255, 255);
retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, keyedStr, &DDS_HANDLE_NIL);
DDS_KeyedString_delete(keyedStr);
/* Write some data using individual strings */
retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1", "Value 1", &DDS_HANDLE_NIL);
str = DDS_String_dup("Value 2");
retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1", str, &DDS_HANDLE_NIL);
DDS_String_free(str);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
KeyedStringDataWriter * stringWriter = ... ;
/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255);
ReturnCode_t retCode =
delete keyedStr;
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
KeyedStringDataWriter * stringWriter = ... ;
/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255);
ReturnCode_t retCode =
delete keyedStr;
C++/CLI Example:
using namespace System; using namespace DDS;
...
KeyedStringDataWriter^ stringWriter = ... ;
/* Write some data using the KeyedString */ KeyedString^ keyedStr = gcnew KeyedString();
/* Write some data using individual strings */
String^ str = "Value 2";
C# Example
using System; using DDS;
...
KeyedStringDataWriter stringWriter = ... ;
/* Write some data using the KeyedString */
KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";
keyedStr.value = "Value 1";
stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);
/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);
String str = "Value 2";
stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);
Java Example :
import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;
...
KeyedStringDataWriter stringWriter = ... ;
/* Write some data using the KeyedString */ KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";
keyedStr.value = "Value 1";
stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);
/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);
String str = "Value 2";
stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);
3.2.5.3Keyed String DataReader
The KeyedString DataReader API is extended with the following operations (in addition to the standard methods described in Using a
DDS::ReturnCode_t DDS::KeyedStringDataReader::get_key_value(
char * key, const DDS::InstanceHandle_t* handle);
DDS::InstanceHandle_t DDS::KeyedStringDataReader::lookup_instance(
const char * key);
For additional information and a complete description of these operations in all supported languages, see the API Reference HTML documentation, which is available for all supported programming languages.
Memory considerations in copy operations:
For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.
If the fields are not initialized to NULL, the behavior depends on the language:
•In Java and .NET, the memory associated to the fields 'value' and 'key' will be reallocated with every sample.
•In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.
The following examples show how to read keyed strings with a keyed string
C Example:
struct DDS_KeyedStringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedKeyedStringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;
int i;
/* Take and print the data */
retCode = DDS_KeyedStringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
for (i = 0; i < DDS_KeyedStringSeq_get_length(&data_seq); ++i) {
if (DDS_SampleInfoSeq_get_reference(&info_seq,
DDS_KeyedStringSeq_get_reference(&data_seq, i));
}
}
/* Return loan */
retCode = DDS_KeyedStringDataReader_return_loan( stringReader, &data_seq, &info_seq);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
KeyedStringSeq dataSeq;
SampleInfoSeq infoSeq;
KeyedStringDataReader * stringReader = ... ;
/* Take a print the data */
ReturnCode_t retCode =
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {
KeyedStringTypeSupport::print_data(&dataSeq[i]);
}
}
/* Return loan */
retCode =
C++/CLI Example:
using namespace System; using namespace DDS;
...
KeyedStringSeq^ dataSeq = gcnew KeyedStringSeq();
SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();
KeyedStringDataReader^ stringReader = ... ;
/* Take and print the data */
ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if
}
}
/* Return loan */
C# Example:
using System; using DDS;
...
KeyedStringSeq dataSeq = new KeyedStringSeq();
SampleInfoSeq infoSeq = new SampleInfoSeq();
KeyedStringDataReader stringReader = ... ;
/* Take and print the data */ stringReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {
KeyedStringTypeSupport.print_data(dataSeq.get_at(i));
}
}
/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);
Java Example:
import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;
...
KeyedStringSeq dataSeq = new KeyedStringSeq();
SampleInfoSeq infoSeq = new SampleInfoSeq();
KeyedStringDataReader stringReader = ... ;
/* Take and print the data */ stringReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) {
if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((
(KeyedString)dataSeq.get(i)).toString());
}
}
/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);
3.2.6Octets
The octets
C/C++ Representation (without Namespaces):
struct DDS_Octets { int length;
unsigned char * value;
};
C++/CLI Representation:
namespace DDS {
public ref struct Bytes: { public:
System::Int32 length; System::Int32 offset; array<System::Byte>^ value;
...
};
};
C# Representation:
namespace DDS {
public class Bytes {
public System.Int32 length; public System.Int32 offset; public System.Byte[] value;
...
};
};
Java Representation:
package com.rti.dds.type.builtin;
public class Bytes implements Copyable { public int length;
public int offset; public byte[] value;
...
};
3.2.6.1Creating and Deleting Octets
Connext provides a set of constructors/destructors to create and destroy Octet objects. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module,
If you want to manipulate the memory of the value field inside the Octets struct in C/C++, use the operations DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and
DDS::OctetBuffer_free(), described in the API Reference HTML documentation (select
Modules, DDS API Reference, Infrastructure Module, Octet Buffer Support).
3.2.6.2Octets DataWriter
In addition to the standard methods (see Using a
DDS::ReturnCode_t DDS::OctetsDataWriter::write(
const DDS::OctetSeq & octets,
const DDS::InstanceHandle_t & handle);
DDS::ReturnCode_t DDS::OctetsDataWriter::write(
const unsigned char * octets, int length,
const DDS::InstanceHandle_t& handle);
DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const DDS::OctetSeq & octets,
const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);
DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const unsigned char * octets, int length,
const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);
These methods are introduced to provide maximum flexibility in the format of the input parameters for the write operations. For additional information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.
The following examples show how to write an array of octets using an octets
C Example:
DDS_OctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;
struct DDS_Octets * octets = NULL; char * octetArray = NULL;
/* Write some data using the Octets structure */ octets = DDS_Octets_new_w_size(1024);
retCode = DDS_OctetsDataWriter_write(octetsWriter, octets, &DDS_HANDLE_NIL);
DDS_Octets_delete(octets);
/* Write some data using an octets array */
octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;
octetArray[1] = 47;
retCode = DDS_OctetsDataWriter_write_octets (octetsWriter, octetArray, 2, &DDS_HANDLE_NIL);
free(octetArray);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
OctetsDataWriter * octetsWriter = ... ;
/* Write some data using the Octets structure */ Octets * octets = new Octets(1024);
ReturnCode_t retCode =
delete octets;
/* Write some data using an octet array */
unsigned char * octetArray = new unsigned char[1024]; octetArray[0] = 46;
octetArray[1] = 47;
retCode =
delete []octetArray;
C++/CLI Example:
using namespace System; using namespace DDS;
...
BytesDataWriter^ octetsWriter = ...;
/* Write some data using Bytes */ Bytes^ octets = gcnew Bytes(1024);
octets.offset = 0;
/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;
octetArray[1] = 47;
C# Example:
using System; using DDS;
...
BytesDataWriter stringWriter = ...;
/* Write some data using the Bytes */ Bytes octets = new Bytes(1024); octets.value[0] = 46; octets.value[1] = 47;
octets.length = 2; octets.offset = 0;
octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);
/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;
octetArray[1] = 47;
octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);
Java Example:
import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;
...
BytesDataWriter octetsWriter = ... ;
/* Write some data using the Bytes class*/ Bytes octets = new Bytes(1024); octets.length = 2;
octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;
octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);
/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;
octetArray[1] = 47;
octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);
3.2.6.3Octets DataReader
The octets DataReader API matches the standard DataReader API (see Using a
Memory considerations in copy operations:
For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the field 'value' if it is initialized to NULL.
If the field 'value' is not initialized to NULL, the behavior depends on the language:
•In Java and .NET, the memory for the field 'value' will be reallocated if the current size is not large enough to hold the received data.
•In C and C++, the memory associated with the field 'value' must be big enough to hold the received data. Insufficient memory may result in crashes.
The following examples show how to read octets with an octets
C Example:
struct DDS_OctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_OctetsDataReader * octetsReader = ... ; DDS_ReturnCode_t retCode;
int i;
/* Take and print the data */
retCode = DDS_OctetsDataReader_take(octetsReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
for (i = 0; i < DDS_OctetsSeq_get_length(&dataSeq); ++i) {
if (DDS_SampleInfoSeq_get_reference(&infoSeq,
DDS_OctetsSeq_get_reference(&dataSeq, i));
}
}
/* Return loan */ retCode =
DDS_OctetsDataReader_return_loan(octetsReader, &dataSeq, &infoSeq);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
OctetsSeq dataSeq; SampleInfoSeq infoSeq;
OctetsDataReader * octetsReader = ... ;
/* Take a print the data */
ReturnCode_t retCode =
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {
OctetsTypeSupport::print_data(&dataSeq[i]);
}
}
/* Return loan */
retCode =
C++/CLI Example:
using namespace System; using namespace DDS;
...
BytesSeq^ dataSeq = gcnew BytesSeq();
SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();
BytesDataReader^ octetsReader = ... ;
/* Take and print the data */
for (int i = 0; i < data_seq.length(); ++i) { if
}
}
/* Return loan */
C# Example:
using System; using DDS;
...
BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;
/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {
BytesTypeSupport.print_data(dataSeq.get_at(i));
}
}
/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);
Java Example:
import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;
...
BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;
/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) {
if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((Bytes)dataSeq.get(i)).toString());
}
}
/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);
3.2.7KeyedOctets
The keyed octets
C/C++ Representation (without Namespaces):
struct DDS_KeyedOctets { char * key;
int length;
unsigned char * value;
};
C++/CLI Representation:
namespace DDS {
public ref struct KeyedBytes { public:
System::String^ key; System::Int32 length; System::Int32 offset; array<System::Byte>^ value;
...
};
};
C# Representation:
namespace DDS {
public class KeyedBytes { public System.String key; public System.Int32 length; public System.Int32 offset; public System.Byte[] value;
…
};
};
Java Representation:
package com.rti.dds.type.builtin; public class KeyedBytes {
public String key; public int length; public int offset; public byte[] value;
...
};
3.2.7.1Creating and Deleting KeyedOctets
Connext provides a set of constructors/destructors to create/destroy KeyedOctets objects. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module,
To manipulate the memory of the value field in the KeyedOctets struct in C/C++: use
DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and DDS::OctetBuffer_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, Octet Buffer Support).
To manipulate the memory of the key field in the KeyedOctets struct in C/C++: use
DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).
3.2.7.2Keyed Octets DataWriter
In addition to the standard methods (see Using a
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose( const char* key,
const DDS::InstanceHandle_t & instance_handle);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose_w_timestamp( const char* key,
const DDS::InstanceHandle_t & instance_handle, const DDS::Time_t & source_timestamp);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::get_key_value( char * key,
const DDS::InstanceHandle_t& handle);
DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::lookup_instance(
const char * key);
DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::register_instance(
const char* key);
DDS::InstanceHandle_t
DDS::KeyedOctetsDataWriter::register_instance_w_timestamp(
const char * key,
const DDS::Time_t & source_timestamp);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance( const char * key,
const DDS::InstanceHandle_t & handle);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance_w_timestamp(
const char* key,
const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,
const unsigned char * octets, int length,
const DDS::InstanceHandle_t& handle);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,
const DDS::OctetSeq & octets,
const DDS::InstanceHandle_t & handle);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,
const unsigned char * octets, int length,
const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);
DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,
const DDS::OctetSeq & octets,
const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);
These methods are introduced to provide maximum flexibility in the format of the input parameters for the write and instance management operations. For more information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.
The following examples show how to write keyed octets using a keyed octets
C Example:
DDS_KeyedOctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;
struct DDS_KeyedOctets * octets = NULL; char * octetArray = NULL;
/* Write some data using the KeyedOctets structure */ octets = DDS_KeyedOctets_new_w_size(128,1024);
retCode = DDS_KeyedOctetsDataWriter_write(
octetsWriter, octets, &DDS_HANDLE_NIL);
DDS_KeyedOctets_delete(octets);
/* Write some data using an octets array */ octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;
octetArray[1] = 47;
retCode = DDS_KeyedOctetsDataWriter_write_octets_w_key ( octetsWriter, "Key 1", octetArray, 2, &DDS_HANDLE_NIL);
free(octetArray);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
KeyedOctetsDataWriter * octetsWriter = ... ;
/* Write some data using the KeyedOctets structure */ KeyedOctets * octets = new KeyedOctets(128,1024);
ReturnCode_t |
retCode = |
delete octets; |
|
/* Write some |
data using an octet array */ |
unsigned char |
* octetArray = new unsigned char[1024]; |
octetArray[0] |
= 46; |
octetArray[1] |
= 47; |
retCode =
delete []octetArray;
C++/CLI Example:
using namespace System; using namespace DDS;
...
KeyedOctetsDataWriter^ octetsWriter = ... ;
/* Write some data using KeyedBytes */ KeyedBytes^ octets = gcnew KeyedBytes(1024);
/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;
octetArray[1] = 47;
"Key 1", octetArray, 0, 2, InstanceHandle_t::HANDLE_NIL);
C# Example:
using System; using DDS;
...
KeyedBytesDataWriter stringWriter = ... ;
/* Write some data using the KeyedBytes */ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";
octets.value[0] = 46; octets.value[1] = 47; octets.length = 2; octets.offset = 0;
octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);
/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;
octetArray[1] = 47;
octetsWriter.write(
"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);
Java Example:
import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;
...
KeyedBytesDataWriter octetsWriter = ... ;
/* Write some data using the KeyedBytes class*/ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";
octets.length = 2; octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;
octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);
/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;
octetArray[1] = 47; octetsWriter.write(
"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);
3.2.7.3Keyed Octets DataReader
The KeyedOctets DataReader API is extended with the following methods (in addition to the standard methods described in Using a
DDS::ReturnCode_t DDS::KeyedOctetsDataReader::get_key_value( char * key,
const DDS::InstanceHandle_t* handle);
DDS::InstanceHandle_t DDS::KeyedOctetsDataReader::lookup_instance(
const char * key);
For more information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.
Memory considerations in copy operations:
For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.
If the fields are not initialized to NULL, the behavior depends on the language:
•In Java and .NET, the memory of the field 'value' will be reallocated if the current size is not large enough to hold the received data. The memory associated with the field 'key' will be reallocated with every sample (the key is an immutable object).
•In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.
The following examples show how to read keyed octets with a keyed octets
C Example:
struct DDS_KeyedOctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedOctetsDataReader * octetsReader = ... ; DDS_ReturnCode_t retCode;
int i;
/* Take and print the data */
retCode = DDS_KeyedOctetsDataReader_take( octetsReader,
&dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
for (i = 0; i < DDS_KeyedOctetsSeq_get_length(&data_seq); ++i) {
if (DDS_SampleInfoSeq_get_reference(&info_seq,
DDS_KeyedOctetsSeq_get_reference(&data_seq, i));
}
}
/* Return loan */
retCode = DDS_KeyedOctetsDataReader_return_loan( octetsReader, &data_seq, &info_seq);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
KeyedOctetsSeq dataSeq; SampleInfoSeq infoSeq;
KeyedOctetsDataReader * octetsReader = ... ;
/* Take a print the data */
ReturnCode_t retCode = octetsReader->take( dataSeq, infoSeq, LENGTH_UNLIMITED,
ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE); for (int i = 0; i < data_seq.length(); ++i) {
if (infoSeq[i].valid_data) { KeyedOctetsTypeSupport::print_data(&dataSeq[i]);
}
}
/* Return loan */
retCode =
C++/CLI Example:
using namespace System; using namespace DDS;
...
KeyedBytesSeq^ dataSeq = gcnew KeyedBytesSeq(); SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq(); KeyedBytesDataReader^ octetsReader = ... ;
/* Take and print the data */
ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE,
ViewStateKind::ANY_VIEW_STATE,
InstanceStateKind::ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if
}
}
/* Return loan */
C# Example:
using System; using DDS;
...
KeyedBytesSeq dataSeq = new KeyedButesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;
/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {
KeyedBytesTypeSupport.print_data(dataSeq.get_at(i));
}
}
/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);
Java Example:
import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;
...
KeyedBytesSeq dataSeq = new KeyedBytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;
/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,
ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);
for (int i = 0; i < data_seq.length(); ++i) {
if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((KeyedBytes)dataSeq.get(i)).toString());
}
}
/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);
3.2.8Managing Memory for
When a sample is written, the DataWriter serializes it and stores the result in a buffer obtained from a pool of preallocated buffers. In the same way, when a sample is received, the DataReader deserializes it and stores the result in a sample coming from a pool of preallocated samples.
For data types generated by rtiddsgen, the size of the buffers and samples in both pools is known based on the IDL or XML description of the type.
For example:
struct MyString { string<128> value;
};
This
However, for
For example, a video surveillance application that is using the keyed octets
To accommodate both kinds of applications and optimize memory usage, you can configure the maximum size of the
Note: These properties must be set consistently with respect to the corresponding *.max_size properties in the DomainParticipant (see Table 3.14 on page
DomainParticipant.
Section 3.2.8.1 includes examples of how to set the maximum size of a string
<dds>
<qos_library name="BuiltinExampleLibrary"> <qos_profile name="BuiltinExampleProfile">
<datawriter_qos> <property>
<value>
<element> <name>dds.builtin_type.string.alloc_size</name> <value>2048</value>
</element>
</value>
</property> </datawriter_qos> <datareader_qos>
<property>
<value>
<element>
<name>dds.builtin_type.string.alloc_size</name> <value>2048</value>
</element>
</value>
</property> </datareader_qos>
</qos_profile> </qos_library>
</dds>
Table 3.1 Properties for Allocating Size of
Property |
|
|
Description |
|
|
|
||
Type |
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
||||||
|
|
Maximum size of the strings published by the DataWriter |
||||||
|
|
or received by the DataReader (includes the NULL- |
||||||
string |
dds.builtin_type.string.alloc_size |
terminated character). |
|
|
|
|
||
|
|
Default: dds.builtin_type.string.max_size if defined (see |
||||||
|
|
Table 3.14 on page |
|
|
|
|||
|
|
|
||||||
|
|
Maximum size of the keys used by the DataWriter or |
||||||
|
dds.builtin_type.keyed_string. |
DataReader (includes the |
|
|||||
|
alloc_key_size |
Default: dds.builtin_type.keyed_string.max_key_size if |
||||||
|
|
defined (see Table 3.14 on page |
|
|||||
keyedstring |
|
|
||||||
|
Maximum size of the strings published by the DataWriter |
|||||||
|
dds.builtin_type.keyed_string. |
or received |
by the DataReader |
(includes |
the |
NULL- |
||
|
terminated character). |
|
|
|
|
|||
|
alloc_size |
|
|
|
|
|||
|
Default: |
dds.builtin_type.keyed_string.max_size |
if |
|||||
|
|
|||||||
|
|
defined (see Table 3.14 on page |
|
|||||
|
|
|
||||||
|
|
Maximum size of the octet sequences published by the |
||||||
octets |
dds.builtin_type.octets.alloc_size |
DataWriter or DataReader. |
|
|
|
|
||
Default: dds.builtin_type.octets.max_size if defined (see |
||||||||
|
|
Table 3.14 on page |
|
|
|
|||
|
|
|
||||||
|
|
Maximum size of the key published by the DataWriter or |
||||||
|
dds.builtin_type.keyed_octets. |
received |
by |
the DataReader |
(includes |
the |
NULL- |
|
|
terminated character). |
|
|
|
|
|||
|
alloc_key_size |
|
|
|
|
|||
|
Default: |
dds.builtin_type.keyed_octets.max_key_size if |
||||||
|
|
|||||||
|
defined (see Table 3.14 on page |
|
||||||
|
|
Maximum size of the octet sequences published by the |
||||||
|
dds.builtin_type.keyed_octets. |
DataWriter or DataReader. |
|
|
|
|
||
|
alloc_size |
Default: |
dds.builtin_type.keyed_octets.max_size |
if |
||||
|
|
defined (see Table 3.14 on page |
|
|||||
|
|
|
|
|
|
|
|
|
3.2.8.1
For simplicity, error handling is not shown in the following examples.
C Example:
DDS_DataWriter * writer = NULL; DDS_StringDataWriter * stringWriter = NULL; DDS_Publisher * publisher = ... ;
DDS_Topic * stringTopic = ... ;
struct DDS_DataWriterQos writerQos = DDS_DataWriterQos_INITIALIZER; DDS_ReturnCode_t retCode;
retCode = DDS_DomainParticipant_get_default_datawriter_qos ( participant, &writerQos);
retCode = DDS_PropertyQosPolicyHelper_add_property ( &writerQos.property, "dds.builtin_type.string.alloc_size", "1000", DDS_BOOLEAN_FALSE);
writer = DDS_Publisher_create_datawriter(
publisher, stringTopic, &writerQos, NULL, DDS_STATUS_MASK_NONE);
stringWriter = DDS_StringDataWriter_narrow(writer); DDS_DataWriterQos_finalize(&writerQos);
C++ Example with Namespaces:
#include "ndds/ndds_namespace_cpp.h" using namespace DDS;
...
Publisher * publisher = ... ;
Topic * stringTopic = ... ;
DataWriterQos writerQos;
ReturnCode_t retCode =
retCode = PropertyQosPolicyHelper::add_property ( &writerQos.property, dds.builtin_type.string.alloc_size",
"1000",
BOOLEAN_FALSE);
DataWriter * writer = publisher->create_datawriter( stringTopic, writerQos, NULL, STATUS_MASK_NONE);
StringDataWriter * stringWriter = StringDataWriter::narrow(writer);
C++/CLI Example:
using namespace DDS;
...
Topic^ stringTopic = ... ;
Publisher^ publisher = ... ;
DataWriterQos^ writerQos = gcnew DataWriterQos();
"dds.builtin_type.string.alloc_size","1000", false);
DataWriter^ writer =
StringDataWriter^ stringWriter = safe_cast<StringDataWriter^>(writer);
C# Example:
using DDS;
...
Topic stringTopic = ... ;
Publisher publisher = ... ;
DataWriterQos writerQos = new DataWriterQos();
participant.get_default_datawriter_qos(writerQos);
PropertyQosPolicyHelper.add_property (writerQos.property_qos,
"dds.builtin_type.string.alloc_size", "1000", false);
StringDataWriter stringWriter =
(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusMask.STATUS_MASK_NONE);
Java Example:
import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;
...
Topic stringTopic = ... ;
Publisher publisher = ... ;
DataWriterQos writerQos = new DataWriterQos();
participant.get_default_datawriter_qos(writerQos);
PropertyQosPolicyHelper.add_property (writerQos.property,
"dds.builtin_type.string.alloc_size", "1000", false);
StringDataWriter stringWriter =
(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusKind.STATUS_MASK_NONE);
3.2.9Type Codes for
The type codes associated with the
module DDS {
/* String */ struct String {
string<max_size> value;
};
/* KeyedString */ struct KeyedString {
string<max_size> key; //@key string<max_size> value;
};
/* Octets */ struct Octets {
sequence<octet, max_size> value;
};
/* KeyedOctets */ struct KeyedOctets {
string<max_size> key; //@key sequence<octet, max_size> value;
};
};
The maximum size (max_size) of the strings and sequences that will be included in the type code definitions can be configured on a
Table 3.2 Properties for Allocating Size of
Property |
|
|
Description |
|
|
|
|
|||
Type |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
||||||||
|
|
Maximum size of the strings published by the DataWriters |
||||||||
|
|
and received by the DataReaders belonging to a |
||||||||
String |
dds.builtin_type.string.max_size |
DomainParticipant (includes the |
||||||||
|
|
character). |
|
|
|
|
|
|
|
|
|
|
Default: 1024 |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
Maximum size of the keys used by the DataWriters and |
||||||||
|
dds.builtin_type.keyed_string. |
DataReaders belonging to a DomainParticipant (includes the |
||||||||
|
max_key_size |
|
|
|
|
|
||||
|
|
Default: 1024 |
|
|
|
|
|
|
|
|
KeyedString |
|
|
||||||||
|
Maximum size of the strings published by the DataWriters |
|||||||||
|
dds.builtin_type.keyed_string. |
and received |
by |
the |
DataReaders |
belonging to |
a |
|||
|
DomainParticipant using |
the |
type (includes |
the |
||||||
|
max_size |
|||||||||
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
||||
|
|
Default: 1024 |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
Maximum size of the octet sequences published by the |
||||||||
Octets |
dds.builtin_type.octets.max_size |
DataWriters |
and |
DataReaders |
belonging |
to |
a |
|||
DomainParticipant. |
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
||
|
|
Default: 2048 |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
Maximum size of the key published by the DataWriter and |
||||||||
|
dds.builtin_type.keyed_octets. |
received by |
the |
DataReaders |
belonging |
to |
the |
|||
|
DomainParticipant (includes |
the |
|
|||||||
|
max_key_size |
|
||||||||
|
character). |
|
|
|
|
|
|
|
|
|
Keyed- |
|
|
|
|
|
|
|
|
|
|
|
Default:1024. |
|
|
|
|
|
|
|
|
|
Octets |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Maximum size of the octet sequences published by the |
|||||||||
|
|
|||||||||
|
dds.builtin_type.keyed_octets. |
DataWriters and DataReaders belonging to a |
||||||||
|
max_size |
DomainParticipant. |
|
|
|
|
|
|
|
|
|
|
Default: 2048 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.3Creating User Data Types with IDL
You can create user data types in a text file using IDL (Interface Description Language). IDL is
Connext only uses a subset of the IDL syntax. IDL was originally defined by the OMG for the use of CORBA client/server applications in an enterprise setting. Not all of the constructs that can be described by the language are as useful in the context of
The rtiddsgen utility will parse any file that follows version 3.0.3 of the IDL specification. It will quietly ignore all syntax that is not recognized by Connext. In addition, even though “anonymous sequences” (sequences of sequences with no intervening typedef) are currently
legal in IDL, they have been deprecated by the specification, and thus rtiddsgen does not support them.
Certain keywords are considered reserved by the IDL specification; see Table 3.3.
Table 3.3 Reserved IDL Keywords
abstract |
emits |
local |
pseudo |
typeid |
|
|
|
|
|
alias |
enum |
long |
public |
typename |
|
|
|
|
|
any |
eventtype |
mirrorport |
publishes |
typeprefix |
|
|
|
|
|
attribute |
exception |
module |
raises |
union |
|
|
|
|
|
boolean |
factory |
multiple |
readonly |
unsigned |
|
|
|
|
|
case |
FALSE |
native |
sequence |
uses |
|
|
|
|
|
char |
finder |
object |
setraises |
valuebase |
|
|
|
|
|
component |
fixed |
octet |
short |
valuetype |
|
|
|
|
|
connector |
float |
oneway |
string |
void |
|
|
|
|
|
const |
getraises |
out |
struct |
wchar |
|
|
|
|
|
consumes |
home |
port |
supports |
wstring |
|
|
|
|
|
context |
import |
porttype |
switch |
|
|
|
|
|
|
custom |
in |
primarykey |
TRUE |
|
|
|
|
|
|
default |
inout |
private |
truncatable |
|
|
|
|
|
|
double |
interface |
provides |
typedef |
|
|
|
|
|
|
The IDL constructs supported by rtiddsgen are described in Table 3.5, “Specifying Data Types in IDL for C and C++,” on page
For C and C++, rtiddsgen uses typedefs instead of the language keywords for primitive types. For example, DDS_Long instead of long or DDS_Double instead of double. This ensures that the types are of the same size regardless of the platform.1
The remainder of this section includes:
❏
❏TypeCode and rtiddsgen (Section 3.3.3)
❏rtiddsgen Translations for IDL Types (Section 3.3.4)
❏Escaped Identifiers (Section 3.3.5)
❏Referring to Other IDL Files (Section 3.3.6)
❏Preprocessor Directives (Section 3.3.7)
❏Using Custom Directives (Section 3.3.8)
1. The number of bytes sent on the wire for each data type is determined by the Common Data Representation (CDR) standard. For details on CDR, please see the Common Object Request Broker Architecture (CORBA) Specification, Version 3.1, Part 2: CORBA Interoperability, Section 9.3, CDR Transfer Syntax (http://www.omg.org/ technology/documents/corba_spec_catalog.htm).
3.3.1
When rtiddsgen generates code for data structures with
For
3.3.1.1Sequences
C, C++, C++/CLI, and C# users can allocate memory from a number of sources: from the heap, the stack, or from a custom allocator of some kind. In those languages, sequences provide the concept of memory "ownership." A sequence may own the memory allocated to it or be loaned memory from another source. If a sequence owns its memory, it will manage its underlying memory storage buffer itself. When a sequence's maximum size is changed, the sequence will free and reallocate its buffer as needed. However, if a sequence was created with loaned memory by user code, then its memory is not its own to free or reallocate. Therefore, you cannot set the maximum size of a sequence whose memory is loaned. See the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, Sequence Support) for more information about how to loan and unloan memory for sequence.
In IDL, as described above, a sequence may be declared as bounded or unbounded. A sequence's "bound" is the greatest value its maximum may take. If you use the initializer functions rtiddsgen provides for your types, all sequences will have their maximums set to their declared bounds. However, the amount of data transmitted on the wire when the sample is written will vary.
3.3.1.2Strings and Wide Strings
The initialization functions that rtiddsgen provides for your types will allocate all of the memory for strings in a type to their declared bounds. Take
To Java and .NET users, an IDL string is a String object: it is immutable and knows its own length. C and C++ users must take care, however, as there is no way to determine how much memory is allocated to a character pointer "string"; all that can be determined is the string's current logical length. In some cases, Connext may need to copy a string into a structure that user code has provided. Connext does not free the memory of the string provided to it, as it cannot know from where that memory was allocated.
In the C and C++ APIs, Connext therefore uses the following conventions:
❏A string's memory is "owned" by the structure that contains that string. Calling the finalization function provided for a type will free all recursively contained strings. If you have allocated a contained string in a special way, you must be careful to clean up your own memory and assign the pointer to NULL before calling the type’s finalize() method, so that Connext will skip over that string.
❏You must provide a
❏When you provide a
Connext provides a small set of C functions for dealing with strings. These functions simplify common tasks, avoid some
3.3.2Value Types
A value type is like a structure, but with support for additional
Readers familiar with value types in the context of CORBA should consult Table 3.4 to see which value
Connext.
Table 3.4 Value Type Support
Aspect |
Level of Support in rtiddsgen |
|
|
|
|
Inheritance |
Single inheritance from other value types |
|
|
|
|
Public state members |
Supported |
|
|
|
|
Private state members |
Become public when code is generated |
|
|
|
|
Custom keyword |
Ignored (the value type is parsed without the keyword and code is generated to |
|
work with it) |
||
|
||
|
|
|
Abstract value types |
No code generated (the value type is parsed, but no code is generated) |
|
|
|
|
Operations |
No code generated (the value type is parsed, but no code is generated) |
|
|
|
|
Truncatable keyword |
Ignored (the value type is parsed without the keyword and code is generated to |
|
work with it) |
||
|
||
|
|
3.3.3TypeCode and rtiddsgen
Type codes are enabled by default when you run rtiddsgen. The
(The
Locally, your application can access the type code for a generated type "Foo" by calling the Foo::get_typecode() operation in the code for the type generated by rtiddsgen (unless
Note:
3.3.4rtiddsgen Translations for IDL Types
This section describes how to specify your data types in an IDL file. The rtiddsgen utility supports all the types listed in the following tables:
❏Table 3.5, “Specifying Data Types in IDL for C and C++,” on page
❏Table 3.6, “Specifying Data Types in IDL for C++/CLI,” on page
❏Table 3.7, “Specifying Data Types in IDL for Java,” on page
In each table, the middle column shows the syntax for an IDL data type in the IDL file. The rightmost column shows the corresponding language mapping created by rtiddsgen.
Table 3.5 Specifying Data Types in IDL for C and C++
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
|
|
|
|
|
char |
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
{ |
|||
(see Note 1 |
char char_member; |
||
DDS_Char char_member; |
|||
below) |
}; |
||
} PrimitiveStruct; |
|||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
wchar |
{ |
||
wchar wchar_member; |
|||
DDS_Wchar wchar_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
|
{ |
||
octet |
octet octet_member; |
||
DDS_Octet octect_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
short |
{ |
||
short short_member; |
|||
DDS_Short short_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
unsigned |
{ |
||
unsigned short |
|||
DDS_UnsignedShort |
|||
short |
unsigned_short_member; |
||
unsigned_short_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
long |
{ |
||
long long_member; |
|||
DDS_Long long_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
unsigned |
{ |
||
unsigned long |
|||
DDS_UnsignedLong |
|||
long |
unsigned_long_member; |
||
unsigned_long_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
|
{ |
||
long long |
long long long_long_member; |
||
DDS_LongLong long_long_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
unsigned |
{ |
||
unsigned long long |
|||
DDS_UnsignedLongLong |
|||
long long |
unsigned_long_long_member; |
||
unsigned_long_long_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
float |
{ |
||
float float_member; |
|||
DDS_Float float_member; |
|||
|
}; |
||
|
} PrimitiveStruct; |
||
|
|
||
|
|
|
Table 3.5 Specifying Data Types in IDL for C and C++
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
||
|
|
|
|
|
|
|
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
double |
{ |
|||
double double_member; |
||||
DDS_Double double_member; |
||||
|
|
}; |
||
|
|
} PrimitiveStruct; |
||
|
|
|
||
|
|
|
|
|
long |
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
double |
{ |
|||
long double long_double_member; |
||||
(see Note 2 |
DDS_LongDouble long_double_member; |
|||
}; |
||||
} PrimitiveStruct; |
||||
below) |
|
|||
|
|
|
||
pointer |
struct MyStruct { |
typedef struct MyStruct { |
||
(see Note 9 |
long * member; |
DDS_Long * member; |
||
below) |
}; |
} MyStruct; |
||
|
|
|
|
|
|
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
boolean |
{ |
|||
boolean boolean_member; |
||||
DDS_Boolean boolean_member; |
||||
|
|
}; |
||
|
|
} PrimitiveStruct; |
||
|
|
|
||
|
|
|
|
|
|
|
enum PrimitiveEnum { |
typedef enum PrimitiveEnum |
|
|
|
{ |
||
|
|
ENUM1, |
||
|
|
ENUM1, |
||
|
|
ENUM2, |
||
|
|
ENUM2, |
||
|
|
ENUM3 |
||
|
|
ENUM3 |
||
|
|
}; |
||
|
|
} PrimitiveEnum; |
||
|
|
|
||
enum |
|
|
|
|
|
|
enum PrimitiveEnum { |
typedef enum PrimitiveEnum |
|
|
|
{ |
||
|
|
ENUM1 = 10, |
||
|
|
ENUM1 = 10, |
||
|
|
ENUM2 = 20, |
||
|
|
ENUM2 = 20, |
||
|
|
ENUM3 = 30 |
||
|
|
ENUM3 = 30 |
||
|
|
}; |
||
|
|
} PrimitiveEnum; |
||
|
|
|
||
|
|
|
|
|
|
|
|
C: #define SIZE 5 |
|
constant |
const short SIZE = 5; |
C++: static const DDS_Short size = 5; |
||
|
|
|
|
|
|
|
|
typedef struct BitfieldType |
|
|
|
struct BitfieldType { |
{ |
|
|
|
short myShort_1 : 1; |
DDS_Short myShort_1 : 1; |
|
|
|
unsigned short myUnsignedShort_1: |
DDS_UnsignedShort myUnsignedShort_1 |
|
|
|
1; |
: 1; |
|
|
|
long myLong_1: 1; |
DDS_Long myLong_1 : 1; |
|
|
|
unsigned long myUnsignedLong_1 :1; |
DDS_UnsignedLong myUnsignedLong_1 : |
|
bitfield |
char myChar_1 : 1; |
1; |
||
wchar myWChar_1 : 1; |
DDS_Char myChar_1 : 1; |
|||
|
|
|||
|
|
octet myOctet_1 : 1; |
DDS_Wchar myWChar_1 : 1; |
|
(see |
short : 0; |
DDS_Octet myOctet_1 : 1; |
||
12 below) |
long myLong_5 : 5; |
DDS_Short : 0; |
||
long myLong_30 : 30; |
DDS_Long myLong_5 : 5; |
|||
|
|
|||
|
|
short myShort_6 : 6; |
DDS_Long myLong_30 : 30; |
|
|
|
short myShort_3and4 : 3+4; |
DDS_Short myShort_6 : 6; |
|
|
|
short myShort; |
DDS_Short myShort_3and4 : 3+4; |
|
|
|
short myShort_8 : 8; |
DDS_Short myShort; |
|
|
|
long myLong_32: 32; |
DDS_Short myShort_8 : 8; |
|
|
|
}; |
DDS_Long myLong_32 : 32; |
|
|
|
|
} BitfieldType; |
|
|
|
|
|
|
struct |
|
struct PrimitiveStruct { |
typedef struct PrimitiveStruct |
|
|
|
|||
|
|
{ |
||
|
|
char char_member; |
||
(see |
char char_member; |
|||
}; |
||||
} PrimitiveStruct; |
||||
10 below) |
|
|||
|
|
|||
|
|
|
|
Table 3.5 Specifying Data Types in IDL for C and C++
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct PrimitiveUnion |
|
|
union |
|
union PrimitiveUnion switch (long){ |
{ |
|
|
|
|
case 1: |
DDS_Long _d; |
|
|
(see Note 3 |
short short_member; |
struct { |
|
|
|
default: |
DDS_Short short_member; |
|
|||
and |
|
||||
long long_member; |
DDS_Long long_member; |
|
|||
10 below) |
}; |
} _u; |
|
|
|
|
|
|
} PrimitiveUnion; |
|
|
|
|
|
|
||
typedef |
typedef short TypedefShort; |
typedef DDS_Short TypedefShort; |
|
||
|
|
|
|
|
|
|
|
struct OneDArrayStruct { |
typedef struct OneDArrayStruct |
|
|
|
|
{ |
|
|
|
|
|
short short_array[2]; |
|
|
|
|
|
DDS_Short short_array[2]; |
|
||
array |
of |
}; |
|
||
} OneDArrayStruct; |
|
|
|||
above |
|
struct TwoDArrayStruct { |
|
|
|
types |
|
typedef struct TwoDArrayStruct |
|
||
|
short short_array[1][2]; |
|
|||
|
|
{ |
|
|
|
|
|
}; |
|
|
|
|
|
DDS_Short short_array[1][2]; |
|
||
|
|
|
|
||
|
|
|
} TwoDArrayStruct; |
|
|
|
|
|
|
|
|
bounded |
|
typedef struct SequenceStruct |
|
||
sequence of |
|
|
|||
|
{ |
|
|
||
above |
|
|
|
|
|
|
struct SequenceStruct { |
DDSShortSeq short_sequence; |
|
||
types |
|
sequence<short,4> short_sequence; |
} SequenceStruct; |
|
|
|
|
}; |
Note: Sequences of primitive types have been |
||
(see |
|
||||
|
predefined by Connext. |
|
|
||
11 below) |
|
|
|
||
|
|
|
|
||
|
|
|
|
|
|
unbounded |
|
typedef struct SequenceStruct |
|
||
|
{ |
|
|
||
sequence of |
|
|
|
||
|
DDSShortSeq short_sequence; |
|
|||
above |
|
struct SequenceStruct { |
} SequenceStruct; |
|
|
types |
|
sequence<short> short_sequence; |
Note: rtiddsgen will supply a default bound. |
||
|
|
}; |
|||
(see |
|
You can specify that bound |
with the |
“- |
|
|
sequenceSize” |
option; |
see |
||
11 below) |
|
||||
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
array |
of |
struct ArraysOfSequences{ |
typedef struct ArraysOfSequences |
|
|
sequence<short,4> |
{ |
|
|
||
sequences |
sequences_array[2]; |
DDS_ShortSeq sequences_array[2]; |
|
||
|
|
}; |
} ArraysOfSequences; |
|
|
|
|
|
|
|
|
|
|
|
typedef DDS_Short ShortArray[2]; |
|
|
|
|
|
DDS_SEQUENCE_NO_GET(ShortArraySeq, |
|
|
|
|
|
ShortArray); |
|
|
sequence of |
typedef short ShortArray[2]; |
typedef struct SequenceOfArrays |
|
||
arrays |
|
|
|
||
|
struct SequenceofArrays { |
{ |
|
|
|
|
|
|
|
||
(see |
sequence<ShortArray,2> |
ShortArraySeq arrays_sequence; |
|
||
arrays_sequence; |
} SequenceOfArrays; |
|
|
||
11 below) |
}; |
DDS_SEQUENCE_NO_GET is a Connext |
|||
|
|
|
|||
|
|
|
macro that defines a new sequence type for a |
||
|
|
|
user data type. In this case, the user data type is |
||
|
|
|
ShortArray. |
|
|
|
|
|
|
|
|
Table 3.5 Specifying Data Types in IDL for C and C++
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
|||
|
|
|
|
||
|
|
|
|
||
|
typedef sequence<short,4> |
typedef DDS_ShortSeq ShortSequence; |
|
||
sequence of |
|
|
|
|
|
sequences |
ShortSequence; |
DDS_SEQUENCE(ShortSequenceSeq, |
|
||
|
|
||||
|
struct SequencesOfSequences{ |
|
ShortSequence); |
|
|
|
|
|
|
|
|
(see Note 4 |
sequence<ShortSequence,2> |
typedef struct SequencesOfSequences{ |
|
||
sequences_sequence; |
|
||||
and Note |
ShortSequenceSeq |
|
|
||
}; |
|
|
|||
11 below) |
sequences_sequence; |
|
|
||
|
|
|
|||
|
|
} SequencesOfSequences; |
|
|
|
|
|
|
|
||
bounded |
struct PrimitiveStruct { |
typedef struct PrimitiveStruct { |
|
||
char* string_member; |
|
|
|||
string<20> string_member; |
|
|
|||
string |
|
/* maximum length = (20) */ |
|||
}; |
|
||||
|
} PrimitiveStruct; |
|
|
||
|
|
|
|
||
|
|
|
|
||
|
|
typedef struct PrimitiveStruct { |
|
||
|
|
char* string_member; |
|
|
|
|
struct PrimitiveStruct { |
|
/* maximum length = (255) */ |
||
unbounded |
} PrimitiveStruct; |
|
|
||
string string_member; |
|
|
|||
|
|
|
|
||
string |
}; |
Note: rtiddsgen will supply a default bound. |
|||
|
|
||||
|
|
You can specify that bound with the - |
|||
|
|
stringSize |
option, |
see |
|
|
|
|
|
||
|
|
|
|
||
|
|
typedef struct PrimitiveStruct { |
|
||
bounded |
struct PrimitiveStruct { |
DDS_Wchar * wstring_member; |
|
||
wstring<20> wstring_member; |
|
/* maximum length = (20) |
|||
wstring |
|
||||
}; |
*/ |
|
|
|
|
|
|
|
|
||
|
|
} PrimitiveStruct; |
|
|
|
|
|
|
|
||
|
|
typedef struct PrimitiveStruct { |
|
||
unbounded |
struct PrimitiveStruct { |
DDS_Wchar * wstring_member; |
|
||
|
/* maximum length = (255) */ |
||||
wstring |
wstring wstring_member; |
} PrimitiveStruct; |
|
|
|
}; |
|
|
|||
|
|
|
|
|
|
|
|
Note: rtiddsgen will supply a default bound. |
|
||
|
|
|
|
||
|
|
With the |
(only available |
||
|
|
for C++): |
|
|
|
|
|
namespace PackageName{ |
|
||
|
module PackageName { |
|
typedef struct Foo { |
|
|
module |
struct Foo { |
|
DDS_Long field; |
|
|
long field; |
|
} Foo; |
|
|
|
|
}; |
}; |
|
|
|
|
}; |
Without the |
|
||
|
|
typedef struct PackageName_Foo { |
|||
|
|
|
DDS_Long field; |
|
|
|
|
} PackageName_Foo; |
|
|
|
|
|
|
|
|
|
Table 3.5 Specifying Data Types in IDL for C and C++
|
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C++: |
class MyValueType { |
|
|
|
|
|
public: |
|
|
|
|
|
MyValueType2 * member; |
|
|
|
|
|
}; |
|
|
|
|
|
class MyValueType { |
|
|
|
|
|
public: |
|
|
|
valuetype MyValueType { |
|
MyValueType2 |
member; |
|
|
|
}; |
|
|
|
|
public MyValueType2 * member; |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
class MyValueType : public MyBa- |
|
|
|
|
|
||
|
valuetype |
|
|
seValueType |
|
|
valuetype MyValueType { |
|
{ |
|
|
|
|
|
public: |
|
|
|
|
public MyValueType2 member; |
|
|
|
|
(see Note 9 |
|
MyValueType2 * member; |
||
|
}; |
|
|||
|
|
}; |
|
||
|
and Note |
|
|
|
|
|
|
|
|
|
|
|
|
C: |
|
|
|
|
10 below) |
|
typedef struct MyValueType { |
||
|
|
valuetype MyValueType: MyBaseValueType |
|
MyValueType2 * member; |
|
|
|
{ |
|
} MyValueType; |
|
|
|
public MyValueType2 * member; |
|
|
|
|
|
}; |
|
typedef struct MyValueType { |
|
|
|
|
|
MyValueType2 |
member; |
|
|
|
|
} MyValueType; |
|
|
|
|
|
typedef struct MyValueType |
|
|
|
|
|
{ |
|
|
|
|
|
MyBaseValueType parent; |
|
|
|
|
|
MyValueType2 * member; |
|
|
|
|
|
} MyValueType; |
|
|
|
|
|
|
|
Table 3.6 Specifying Data Types in IDL for C++/CLI |
|
|
|
||
|
|
|
|
||
|
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
||
|
|
|
|
||
|
|
|
|
||
|
char |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
(see Note 1 |
char char_member; |
System::Char char_member; |
||
|
below) |
}; |
}; |
|
|
|
|
|
|
||
|
wchar |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
wchar wchar_member; |
System::Char wchar_member; |
|||
|
|
}; |
}; |
|
|
|
|
|
|
||
|
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
octet |
octet octet_member; |
System::Byte octet_member; |
||
|
|
}; |
}; |
|
|
|
|
|
|
||
|
short |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
short short_member; |
System::Int16 short_member; |
|||
|
|
}; |
}; |
|
|
|
|
|
|
|
|
|
unsigned |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
unsigned short |
||||
|
System::UInt16 unsigned_short_member; |
||||
|
short |
unsigned_short_member; |
|||
|
}; |
|
|
||
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
long |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
long long_member; |
System::Int32 long_member; |
|||
|
|
}; |
}; |
|
|
|
|
|
|
||
|
unsigned |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
|
unsigned long unsigned_long_member; |
System::UInt32 unsigned_long_member; |
|||
|
long |
||||
|
}; |
}; |
|
|
|
|
|
|
|
||
|
|
|
|
|
|
Table 3.6 Specifying Data Types in IDL for C++/CLI
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
||
|
|
|
|
|
|
|
|
|
|
long long |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
long long long_long_member; |
System::Int64 long_long_member; |
|||
|
|
}; |
}; |
|
|
|
|
|
|
unsigned |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
||
unsigned long long |
System::UInt64 |
|||
long long |
unsigned_long_long_member; |
unsigned_long_long_member; |
||
|
|
}; |
}; |
|
|
|
|
|
|
float |
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
|
float float_member; |
System::Single float_member; |
||
|
|
}; |
}; |
|
|
|
|
|
|
|
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
double |
double double_member; |
System::Double double_member; |
||
|
|
}; |
} PrimitiveStruct; |
|
|
|
|
|
|
long |
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
double |
||||
long double long_double_member; |
DDS::LongDouble long_double_member; |
|||
(see Note 2 |
||||
}; |
} PrimitiveStruct; |
|||
below) |
|
|
|
|
|
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
boolean |
boolean boolean_member; |
System::Boolean boolean_member; |
||
|
|
}; |
}; |
|
|
|
|
|
|
|
|
|
public enum class |
|
|
|
enum PrimitiveEnum { |
PrimitiveEnum : System::Int32 { |
|
|
|
ENUM1, |
ENUM1, |
|
|
|
ENUM2, |
ENUM2, |
|
|
|
ENUM3 |
ENUM3 |
|
enum |
|
}; |
}; |
|
|
|
|
||
|
|
enum PrimitiveEnum { |
public enum class |
|
|
|
ENUM1 = 10, |
PrimitiveEnum : System::Int32 { |
|
|
|
ENUM2 = 20, |
ENUM1 = 10, |
|
|
|
ENUM3 = 30 |
ENUM2 = 20, |
|
|
|
}; |
ENUM3 = 30 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
public ref class SIZE { |
|
constant |
const short SIZE = 5; |
public: |
||
static System::Int16 VALUE = 5; |
||||
|
|
|
||
|
|
|
}; |
|
|
|
|
|
|
struct |
|
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
|
|
|||
|
|
|
||
(see |
char char_member; |
System::Char char_member; |
||
}; |
}; |
|||
10 below) |
|
|||
|
|
|||
|
|
|
|
|
|
|
|
public ref class PrimitiveUnion |
|
union |
|
union PrimitiveUnion switch (long){ |
{ |
|
|
|
case 1: |
System::Int32 _d; |
|
(see Note 3 |
short short_member; |
struct PrimitiveUnion_u { |
||
default: |
System::Int16 short_member; |
|||
and |
||||
long long_member; |
System::Int32 long_member; |
|||
10 below) |
}; |
} _u; |
||
|
|
|
}; |
|
|
|
|
|
|
array |
of |
struct OneDArrayStruct { |
public ref class OneDArrayStruct { |
|
array<System::Int16>^ short_array; |
||||
above |
|
short short_array[2]; |
||
|
/*length == 2*/ |
|||
types |
|
}; |
||
|
}; |
|||
|
|
|
||
|
|
|
|
Table 3.6 Specifying Data Types in IDL for C++/CLI
IDL Type |
Sample Entry in IDL File |
Sample Output Generated by rtiddsgen |
|||||
|
|
|
|
|
|
||
|
|
|
|
|
|
||
bounded |
|
public ref class SequenceStruct { |
|
||||
sequence of |
|
|
|||||
|
ShortSeq^ short_sequence; |
|
|||||
above |
|
|
|
||||
|
struct SequenceStruct { |
/*max = 4*/ |
|
|
|||
types |
|
sequence<short,4> short_sequence; |
}; |
|
|
|
|
|
|
}; |
Note: Sequences of primitive types have been |
||||
(see |
|
||||||
|
predefined by Connext. |
|
|
||||
11 below) |
|
|
|
||||
|
|
|
|
|
|||
|
|
|
|
||||
unbounded |
|
public ref class SequenceStruct { |
|
||||
sequence of |
|
ShortSeq^ short_sequence; |
|
||||
above |
|
struct SequenceStruct { |
/*max = <default bound>*/ |
|
|||
|
}; |
|
|
|
|||
types |
|
|
|
|
|||
|
sequence<short> short_sequence; |
|
|
|
|||
|
Note: rtiddsgen will supply a default bound. |
||||||
|
|
}; |
|||||
|
|
You can specify that bound with the |
|
||||
(see |
|
|
|||||
|
|||||||
11 below) |
|
|
|
|
|||
|
|
|
|
|
|||
|
|
|
public ref class ArraysOfSequences |
|
|||
array |
of |
struct ArraysOfSequences{ |
{ |
|
|
|
|
sequence<short,4> |
array<DDS::ShortSeq^>^ |
|
|
||||
sequences |
sequences_array[2]; |
sequences_array; |
|
|
|||
|
|
}; |
// maximum length = (2) |
|
|
||
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|||
bounded |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
||||
System::String^ string_member; |
|
||||||
string<20> string_member; |
|
||||||
string |
|
// maximum length = (20) |
|
||||
|
}; |
|
|||||
|
|
}; |
|
|
|
||
|
|
|
|
|
|
||
|
|
|
|
|
|||
|
|
|
public ref class PrimitiveStruct { |
|
|||
|
|
|
System::String^ string_member; |
|
|||
unbounded |
struct PrimitiveStruct { |
// maximum length = (255) |
|
||||
string string_member; |
}; |
|
|
|
|||
string |
|
}; |
Note: rtiddsgen will supply a default bound. |
||||
|
|
|
You can specify that bound with the - |
||||
|
|
|
stringSize |
option, |
see |
||
|
|
|
|
|
|
||
|
|
|
|
|
|||
bounded |
struct PrimitiveStruct { |
public ref class PrimitiveStruct { |
|
||||
System::String^ string_member; |
|
||||||
wstring<20> wstring_member; |
|
||||||
wstring |
// maximum length = (20) |
|
|||||
}; |
|
||||||
|
|
}; |
|
|
|
||
|
|
|
|
|
|
||
|
|
|
|
|
|||
|
|
|
public ref class PrimitiveStruct { |
|
|||
|
|
|
System::String^ string_member; // |
||||
|
|
struct PrimitiveStruct { |
maximum length = (255) |
|
|
||
unbounded |
}; |
|
|
|
|||
wstring |
wstring wstring_member; |
Note: rtiddsgen will supply a default bound. |
|||||
}; |
|||||||
|
|
You can specify that bound with the - |
|||||
|
|
|
|||||
|
|
|
stringSize |
option, |
see |
||
|
|
|
|
|
|
||
|
|
|
|
|
|
||
|
|
module PackageName { |
namespace PackageName { |
|
|
||
module |
struct Foo { |
public ref class Foo { |
|
|
|||
long field; |
System::Int32 field; |
|
|||||
|
|
}; |
}; |
|
|
|
|
|
|
}; |
}; |
|
|
|
|
|
|
|
|
|
|
|
Table 3.7 Specifying Data Types in IDL for Java
IDL Type |
Sample Entry in IDL file |
Sample Java Output Generated by |
||
rtiddsgen |
||||
|
|
|
||
|
|
|
|
|
char |
|
|
public class PrimitiveStruct |
|
|
|
struct PrimitiveStruct { |
{ |
|
(see Note |
char char_member; |
public char char_member; |
||
}; |
... |
|||
below) |
|
|
} |
|
|
|
|
|
|
wchar |
|
|
public class PrimitiveStruct |
|
|
|
struct PrimitiveStruct { |
{ |
|
(see Note |
wchar wchar_member; |
public char wchar_member; |
||
}; |
... |
|||
below) |
|
|
} |
|
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
octet |
|
struct PrimitiveStruct { |
{ |
|
|
octet octet_member; |
public byte byte_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
short |
|
struct PrimitiveStruct { |
{ |
|
|
short short_member; |
public short short_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
unsigned |
|
struct PrimitiveStruct { |
public class PrimitiveStruct |
|
short |
|
|||
|
{ |
|||
|
|
unsigned short |
||
|
|
public short unsigned_short_member; |
||
|
|
unsigned_short_member; |
||
(see Note |
... |
|||
}; |
||||
} |
||||
below) |
|
|
||
|
|
|
||
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
long |
|
struct PrimitiveStruct { |
{ |
|
|
long long_member; |
public int long_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
unsigned |
|
struct PrimitiveStruct { |
public class PrimitiveStruct |
|
long |
|
|||
|
{ |
|||
|
|
unsigned long |
||
|
|
public int unsigned_long_member; |
||
|
|
unsigned_long_member; |
||
(see Note |
... |
|||
}; |
||||
} |
||||
below) |
|
|
||
|
|
|
||
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
long long |
|
struct PrimitiveStruct { |
{ |
|
|
long long long_long_member; |
public long long_long_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
unsigned |
|
|
public class PrimitiveStruct |
|
long long |
|
struct PrimitiveStruct { |
{ |
|
|
|
unsigned long long |
public long |
|
(see Note |
unsigned_long_long_member; |
unsigned_long_long_member; |
||
}; |
... |
|||
below) |
|
|
} |
|
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
float |
|
struct PrimitiveStruct { |
{ |
|
|
float float_member; |
public float float_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
Table 3.7 Specifying Data Types in IDL for Java
IDL Type |
Sample Entry in IDL file |
Sample Java Output Generated by |
||
rtiddsgen |
||||
|
|
|
||
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
double |
|
struct PrimitiveStruct { |
{ |
|
|
double double_member; |
public double double_member; |
||
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
||
long double |
|
public class PrimitiveStruct |
||
|
|
struct PrimitiveStruct { |
{ |
|
(see Note |
long double long_double_member; |
public double long_double_member; |
||
}; |
... |
|||
below) |
|
|
} |
|
|
|
|
|
|
pointer |
|
struct MyStruct { |
public class MyStruct { |
|
|
public int member; |
|||
(see Note |
long * member; |
|||
... |
||||
below) |
|
}; |
||
|
}; |
|||
|
|
|
||
|
|
|
|
|
|
|
|
public class PrimitiveStruct |
|
|
|
struct PrimitiveStruct { |
{ |
|
boolean |
|
boolean boolean_member; |
public boolean boolean_member; |
|
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public class PrimitiveEnum extends Enum |
|
|
|
|
{ |
|
|
|
|
public static PrimitiveEnum ENUM1 = |
|
|
|
|
new PrimitiveEnum ("ENUM1", 0); |
|
|
|
enum PrimitiveEnum { |
public static PrimitiveEnum ENUM2 = |
|
|
|
ENUM1, |
new PrimitiveEnum ("ENUM2", 1); |
|
|
|
ENUM2, |
|
|
|
|
ENUM3 |
public static PrimitiveEnum ENUM3 = |
|
|
|
}; |
new PrimitiveEnum ("ENUM3", 2); |
|
|
|
|
public static PrimitiveEnum |
|
|
|
|
valueOf(int ordinal); |
|
|
|
|
... |
|
enum |
|
|
} |
|
|
|
|
||
|
|
public class PrimitiveEnum extends Enum |
||
|
|
|
||
|
|
|
{ |
|
|
|
|
public static PrimitiveEnum ENUM1 = |
|
|
|
|
new PrimitiveEnum ("ENUM1", 10); |
|
|
|
enum PrimitiveEnum { |
public static PrimitiveEnum ENUM2 = |
|
|
|
ENUM1 = 10, |
new PrimitiveEnum ("ENUM2", 10); |
|
|
|
ENUM2 = 20, |
|
|
|
|
ENUM3 = 30 |
public static PrimitiveEnum ENUM3 = |
|
|
|
}; |
new PrimitiveEnum ("ENUM3", 20); |
|
|
|
|
public static PrimitiveEnum |
|
|
|
|
valueOf(int ordinal); |
|
|
|
|
... |
|
|
|
|
} |
|
|
|
|
|
|
constant |
|
|
public class SIZE { |
|
|
const short SIZE = 5; |
public static final short VALUE = 5; |
||
|
|
|
} |
|
|
|
|
|
Table 3.7 Specifying Data Types in IDL for Java
IDL Type |
Sample Entry in IDL file |
Sample Java Output Generated by |
||
rtiddsgen |
||||
|
|
|
||
|
|
|
|
|
|
|
struct BitfieldType { |
public class BitfieldType |
|
|
|
{ |
||
|
|
short myShort_1 : 1; |
||
|
|
public short myShort_1; |
||
|
|
long myLong_1: 1; |
||
|
|
public int myLong_1; |
||
|
|
char myChar_1 : 1; |
||
|
|
public byte myChar_1; |
||
|
|
wchar myWChar_1 : 1; |
||
|
|
public char myWChar_1; |
||
bitfield |
|
octet myOctet_1 : 1; |
||
|
public byte myOctet_1; |
|||
|
|
short : 0; |
||
|
|
public int myLong_5; |
||
|
|
long myLong_5 : 5; |
||
(see Note 12 |
public int myLong_30; |
|||
long myLong_30 : 30; |
||||
public short myShort_6; |
||||
below) |
|
short myShort_6 : 6; |
||
|
public short myShort_3and4; |
|||
|
|
short myShort_3and4 : 3+4; |
||
|
|
public short myShort; |
||
|
|
short myShort; |
||
|
|
public short myShort_8; |
||
|
|
short myShort_8 : 8; |
||
|
|
public int myLong_32; |
||
|
|
long myLong_32: 32; |
||
|
|
... |
||
|
|
}; |
||
|
|
} |
||
|
|
|
||
|
|
|
|
|
struct |
|
|
public class PrimitiveStruct |
|
|
struct PrimitiveStruct { |
{ |
||
|
|
|||
(see Note 10 |
char char_member; |
public char char_member; |
||
}; |
||||
below) |
|
|
} |
|
|
|
|
||
|
|
|
|
|
union |
|
union PrimitiveUnion switch (long){ |
public class PrimitiveUnion { |
|
|
case 1: |
public int _d; |
||
|
|
|||
|
|
short short_member; |
public short short_member; |
|
(see Note 10 |
default: |
public int long_member; |
||
below) |
|
long long_member; |
... |
|
|
}; |
} |
||
|
|
|||
|
|
|
|
|
typedef |
of |
|
/* typedefs are unwounded to the original |
|
primitives, |
|
|||
typedef short ShortType; |
type when used */ |
|||
enums, |
|
|||
|
|
public class PrimitiveStruct |
||
strings |
|
|
||
|
struct PrimitiveStruct { |
{ |
||
|
|
ShortType short_member; |
public short short_member; |
|
(see Note |
}; |
... |
||
below) |
|
|
} |
|
|
|
|
||
|
|
|
|
|
typedef |
of |
|
/* Wrapper class */ |
|
sequences |
|
|
public class ShortArray |
|
or arrays |
|
typedef short ShortArray[2]; |
{ |
|
|
public short[] userData = new |
|||
|
|
|
||
(see Note |
|
short[2]; |
||
|
... |
|||
below) |
|
|
} |
|
|
|
|
|
|
|
|
|
public class OneDArrayStruct |
|
|
|
struct OneDArrayStruct { |
{ |
|
|
|
public short[] short_array = new |
||
|
|
short short_array[2]; |
||
|
|
short[2]; |
||
|
|
}; |
||
|
|
... |
||
|
|
|
||
array |
|
|
} |
|
|
|
|
||
|
|
public class TwoDArrayStruct |
||
|
|
|
||
|
|
struct TwoDArrayStruct { |
{ |
|
|
|
public short[][] short_array = new |
||
|
|
short short_array[1][2]; |
||
|
|
short[1][2]; |
||
|
|
}; |
||
|
|
... |
||
|
|
|
||
|
|
|
} |
|
|
|
|
|
Table 3.7 Specifying Data Types in IDL for Java
IDL Type |
Sample Entry in IDL file |
Sample Java Output Generated by |
||
rtiddsgen |
||||
|
|
|
||
|
|
|
|
|
|
|
|
public class SequenceStruct |
|
bounded |
|
|
{ |
|
sequence |
|
struct SequenceStruct { |
public ShortSeq short_sequence = new |
|
|
|
sequence<short,4> |
ShortSeq((4)); |
|
(see Note 11 |
short_sequence; |
... |
||
}; |
} |
|||
below) |
|
|
Note: Sequences of primitive types have been |
|
|
|
|
predefined by Connext. |
|
|
|
|
|
|
|
|
|
public class SequenceStruct |
|
unbounded |
|
{ |
||
|
public ShortSeq short_sequence = new |
|||
sequence |
|
struct SequenceStruct { |
ShortSeq((100)); |
|
|
|
sequence<short> short_sequence; |
... |
|
(see Note 11 |
}; |
} |
||
Note: rtiddsgen will supply a default bound. You |
||||
below) |
|
|
||
|
|
can specify that bound with the |
||
|
|
|
||
|
|
|
||
|
|
|
|
|
|
|
|
public class ArraysOfSequences |
|
array |
of |
struct ArraysOfSequences{ |
{ |
|
sequence<short,4> |
public ShortSeq[] sequences_array = |
|||
sequences |
|
sequences_array[2]; |
new ShortSeq[2]; |
|
|
|
}; |
... |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Wrapper class */ |
|
|
|
|
public class ShortArray |
|
|
|
|
{ |
|
|
|
|
public short[] userData = new |
|
|
|
|
short[2]; |
|
|
|
|
... |
|
|
|
|
} |
|
sequence |
of |
typedef short ShortArray[2]; |
/* Sequence of wrapper class objects */ |
|
arrays |
|
|
||
|
struct SequenceOfArrays{ |
public final class ShortArraySeq |
||
|
|
|||
|
|
extends ArraySequence |
||
|
|
sequence<ShortArray,2> |
||
(see Note 11 |
{ |
|||
arrays_sequence; |
||||
... |
||||
below) |
|
}; |
||
|
} |
|||
|
|
|
||
|
|
|
public class SequenceOfArrays |
|
|
|
|
{ |
|
|
|
|
public ShortArraySeq arrays_sequence |
|
|
|
|