Files
qt6-migration-pipeline/external/rti_connext_dds-7.7.0/include/ndds/metp/metp_dds.h
T
torstenandCopilot 342ffd3e5c Update submodule to latest BUILD_RTI fixes
- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten
- svcTabCommon: Export-Header-Fix via Fallback-Target
- TrainingAreaBase: Stub-Header für BUILD_RTI=OFF
- ddsfts: Include-Pfad und Dependency-Fixes
- BUILD_RTI=OFF Compilation vollständig unterstützt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
2026-08-21 19:30:20 +02:00

474 lines
17 KiB
C

/*
* (c) Copyright, Real-Time Innovations, 2010-2024.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef metp_dds_h
#define metp_dds_h
#include "metp/metp_dll.h"
#include "ndds/ndds_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/*e \defgroup METPModuleIDL rtiddsgen
\ingroup RTI
ZCSHMEM requires <b>rtiddsgen</b> to generate additional code to handle
multiple encapsulations. To enable the additional support, annotate types
that require zero copy over shared memory support with
\@transfer_mode(SHMEM_REF). For example:
<p>
\verbatim
@transfer_mode(SHMEM_REF)
struct Foo {
long id;
long data[10000];
};
\endverbatim
If the annotation is used on an unsupported IDL type
(such as a sequence) as a member, an error indicating unsupported type
will be observed during code generation.
\n\n
@section Supported IDL Types
<table>
<tr><th>IDL Construct</th>
<th>Support</th>
</tr>
<tr><th>Modules</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Interfaces</th>
<td valign="top">Ignored</td>
</tr>
<tr><th>Constants</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Basic Data Types</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Enums</th>
<td valign="top">Supported</td>
</tr>
<tr><th>String Types</th>
<td valign="top">Not Supported</td>
</tr>
<tr><th>Wide String Types</th>
<td valign="top">Not Supported</td>
</tr>
<tr><th>Struct Types</th>
<td valign="top">Supported.
Inline nested structures, such as the following example, are not supported.
\verbatim
struct Outer {
short outer_short;
struct Inner {
char inner_char;
short inner_short;
} outer_nested_inner;
};
\endverbatim
</td>
</tr>
<tr><th>Fixed Types</th>
<td valign="top">Ignored</td>
</tr>
<tr><th>Union Types</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Sequence Types</th>
<td valign="top">Not Supported.
</td>
</tr>
<tr><th>Array Types</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Typedefs</th>
<td valign="top">Supported</td>
</tr>
<tr><th>Any</th>
<td valign="top">Not Supported. rtiddsgen does not ignore them. Do not use
this construct in the IDL file.</td>
</tr>
<tr><th>Value Types</th>
<td valign="top">Ignored</td>
</tr>
<tr><th>Exception Types</th>
<td valign="top">Ignored</td>
</tr>
<tr><th>Type Code</th>
<td valign="top">Supported</td>
</tr>
</table>
*/
/*e \defgroup METPModuleAPI ZCSHMEM C and C++ APIs
\ingroup RTI
*/
/*e \defgroup METPModuleAPIC ZCSHMEM C API
\ingroup METPModuleAPI
*/
#ifdef DOXYGEN_DOCUMENTATION_ONLY
/*e \ingroup METPModuleAPIC
\brief Returns a pointer to a sample of IDL type, Foo. The space allocated to
this sample is the maximum size of the IDL type mapped to C.\n\n
The following is a description of the different possible states of a sample:
free, allocated, in use, and removed.\n\n
A sample that has never been allocated is "free". create_data() takes a
"free" or "removed" sample and makes it "allocated". write() takes an
"allocated" or "removed" sample and puts it "in use". An "in use" sample
becomes "removed" when DDS removes it from the writer queue. "Removed"
samples are made "free" when the DDS domain participant is deleted.\n\n
The recommended approach is to create_data, write, create_data, write, etc.
@param self \st_in. Pointer to self. Must not be NULL.
@param initialize \st_in. Controls initialization of the sample when it is
allocated. If \p initialize is DDS_BOOLEAN_TRUE, a
sample will be initialized to zero. If \p initialize
is DDS_BOOLEAN_FALSE, a sample with undefined
contents is returned.
@return Pointer to a sample of type Foo if space is available, NULL otherwise.
Returns NULL only if writer_sample_allocation_settings.max_count samples are
allocated or in use. writer_sample_allocation_settings is available in
shmem_ref_transfer_mode_settings of DataWriter TypeSupportQosPolicy.
The pointer returned is aligned to 8-byte boundary. It is guaranteed that the
distance between any two pointers returned by FooDataWriter_create_data(..)
is at least the maximum size of the IDL type mapped to C.\n\n
When zero copy data over shared memory transport is enabled, RTI DDS will
allocate shared memory based on the standard DDS_ResourceLimitsQosPolicy for the
DataWriter:
-# DDS_ResourceLimitsQosPolicy.initial_samples. The initial amount of bytes
in shared memory allocated by a DataWriter is at least initial_samples * the
maximum size of the IDL type mapped to C.
-# DDS_ResourceLimitsQosPolicy.max_samples. The maximum number of bytes
allocated in shared memory by a DataWriter is at least (max_samples +
max_samples_reserve) * the maximum size of the IDL type mapped to C.
-# It is recommended to set initial_samples = max_samples to minimize the
number of shared memory segments that are created.
-# When the resource-limits are exhausted, no additional samples can be
allocated.
-# If the ResourceLimitsQosPolicy specified on the DataWriter exceeds
available OS system resources, the application may run out of shared memory
space for samples.
-# If the ResourceLimitsQosPolicy specified on the DataWriter exceeds
available OS system resources, FooDataWriter_create_data(..) returns NULL.
*/
void *FooDataWriter_create_data(DDS_DataWriter *self, DDS_Boolean initialize);
/*e \ingroup METPModuleAPIC
\brief Called when a sample is no longer in use and is removed (see
definitions of "in use" and "removed" in the documentation for
FooDataWriter_create_data) and when the DDS_DATA_WRITER_SAMPLE_REMOVED_STATUS
bit is set on the FooDataWriterListener mask. Writing a sample already "in
use" will return this error: METPMemPool_getBufferState:!legal state
@param listener_data \st_in Data associated with the listener when the
listener is set
@param writer \st_out. Locally created DDS_DataWriter that triggers the
listener callback.
@param cookie \st_out. Contains the absolute address of the sample no longer
in use. You can do the following to get the address:\n
\verbatim
void *location = NULL;
location = *(void**)DDS_OctetSeq_get_contiguous_buffer(&cookie.value);
printf("on_sample_removed. location = %p\n", location);
\endverbatim
*/
void FooDataWriterListener_on_sample_removed(
void *listener_data,
DDS_DataWriter *writer,
const struct DDS_Cookie_t *cookie);
/*e \defgroup METPModuleAPICPP ZCSHMEM C++ API
\ingroup METPModuleAPI
*/
/*e \ingroup METPModuleAPICPP
\brief Returns a pointer to a sample of the calling entity's data type. The
space allocated to this sample is the maximum size of the IDL type mapped to
C++.\n\n
The following is a description of the different possible states of a sample:
free, allocated, in use, and removed.\n\n
A sample that has never been allocated is "free". create_data() takes a
"free" or "removed" sample and makes it "allocated". write() takes an
"allocated" or "removed" sample and puts it "in use". An "in use" sample
becomes "removed" when DDS removes it from the writer queue. "Removed"
samples are made "free" when the DDS domain participant is deleted.\n\n
If you have more than one writer in your application, the recommended
approach is to create_data, write, create_data, write, etc.
If writer 1 calls create_data, write, waits for on_sample_removed, and then
writer 2 calls create_data, writer 2 could get the "removed" sample of writer
1. At this point, both writers are working with the same sample, so then when
writer 1 makes an update to the sample, writer 2 will unintentionally get
that update, causing confusion. However, if writer 1 calls create_data before
making the update, it will get a fresh sample different from the one that
writer 2 has, avoiding confusion.
@param self \st_in. Pointer to self. Must not be NULL.
@param initialize \st_in. Controls initialization of the sample when it is
allocated. If \p initialize is DDS_BOOLEAN_TRUE, a
sample will be initialized to zero. If \p initialize
is DDS_BOOLEAN_FALSE, a sample with undefined
contents is returned.
@return Pointer to a sample of type Foo if space is available, NULL
otherwise. Returns NULL only if (the value of the property
dds.data_writer.type_plugin.max_samples_reserve + the value of the QoS
datawriter_qos.resource_limits.max_samples) samples are allocated or in use.
The pointer returned is guaranteed to be aligned with the largest CPU
alignment requirement for any type on a specific platform. On the Cell
platform, the pointer will be aligned on a 128 byte boundary per IBM
performance recommendations. It is guaranteed that the distance between any
two pointers returned by FooDataWriter_create_data(..) is at least the
maximum size of the IDL type mapped to C++.\n\n
When zero copy data over shared memory transport is enabled, RTI DDS will
allocate shared memory based on the standard DDS_ResourceLimitsQosPolicy for the
DataWriter:
-# DDS_ResourceLimitsQosPolicy.initial_samples. The initial amount of bytes
in shared memory allocated by a DataWriter is at least initial_samples * the
maximum size of the IDL type mapped to C++.
-# DDS_ResourceLimitsQosPolicy.max_samples. The maximum number of bytes
allocated in shared memory by a DataWriter is at least (max_samples +
max_samples_reserve) * the maximum size of the IDL type mapped to C++.
-# When the resource-limits are exhausted, no additional samples can be
allocated.
-# If the ResourceLimitsQosPolicy specified on the DataWriter exceeds
available OS system resources, the application may run out of shared memory
space for samples.
-# If the ResourceLimitsQosPolicy specified on the DataWriter exceeds
available OS system resources, FooDataWriter_create_data(..) returns NULL.
*/
void *FooDataWriter_create_data(DDSDataWriter *self, DDS_Boolean initialize);
/*e \ingroup METPModuleAPICPP
\brief Called when a sample is no longer in use and is removed (see
definitions of "in use" and "removed" in the documentation for
FooDataWriter_create_data) and when the DDS_DATA_WRITER_SAMPLE_REMOVED_STATUS
bit is set on the FooDataWriterListener mask. Writing a sample already "in
use" will return this error: METPMemPool_getBufferState:!legal state
@param writer \st_out. Locally created DDS_DataWriter that triggers the
listener callback.
@param cookie \st_out. Contains the absolute address of the sample no longer
in use. You can do the following to get the address:\n
\verbatim
void *location = NULL;
location = *(void**)DDS_OctetSeq_get_contiguous_buffer(&cookie.value);
printf("on_sample_removed. location = %p\n", location);
\endverbatim
*/
virtual void FooDataWriterListener_on_sample_removed(
DDSDataWriter *writer,
const struct DDS_Cookie_t& cookie);
#endif
/*e \defgroup METPModuleExample Examples
\ingroup RTI
ZCSHMEM comes with example applications and QoS profiles, which can be found
in the following locations:
\verbatim
$NDDSHOME/example/C/helloWorldMETP - Example HelloWorld in C
$NDDSHOME/example/CPP/helloWorldMETP - Example HelloWorld in C++
$NDDSHOME/example/CPP/performance/latencyMETP - Example latency test in
C++ $NDDSHOME/example/CPP/performance/throughputMETP - Example throughput
test in C++ \endverbatim <b> Running the Examples </b> <p> To build the
applications, use the provided makefiles. Please make sure that NDDSHOME is
set. For example, to compile HelloWorld: \verbatim declare -x NDDSHOME=<path>
make -f makefile_HelloWorld_x64Linux2.6gcc4.5.1
\endverbatim
After running make, you can find the executables in:
\verbatim
./objs/x64Linux2.6gcc4.5.1/HelloWorld_publisher
./objs/x64Linux2.6gcc4.5.1/HelloWorld_subscriber
\endverbatim
All executables have a help option (not all applications support all
options):
\verbatim
./objs/x64Linux2.6gcc4.5.1/HelloWorld_publisher -h
-sleep <ms> - Sleep between each write call in ms. Default=1000
-domain <id> - Domain to join. Default=0
-count <count> - Number of samples to send. 0 = infinite (Default)
-profile <name> - Name of QoS profile to use
-hello - Publish HelloWorld sample
-10mb - Publish 10MB sample
-50mb - Publish 50MB sample
-100mb - Publish 100MB sample
-v - Print non-error messages
\endverbatim
<p>
All the examples follow the general design described below. It is assumed that
you are familiar with the different \ndds read and take APIs, as well as loan
and return semantics. <p> All the QoS are written using the XML profile syntax.
The following example forms the basis for all examples. This example uses the
Multi-Encapsulation Type Support (METP) to publish and subscribe to an IDL type
called MyType.
<b> IDL </b>
<p>
ZCSHMEM requires additonal code to be generated. Use rtiddsgen's -metp option
to enable ZCSHMEM functionality.
\verbatim
MyType.idl
struct MyType {
long x;
long y;
octet data[120];
};
rtiddsgen -language C -metp MyType.idl
\endverbatim
<b> DataWriterQos </b>
Enable ZCSHMEM only for DataWriters that communicate using the \ndds zero-copy
over shared memory transport.
\verbatim
<property>
<value>
<element>
<name>dds.data_writer.type_plugin.disable_zcshmem</name>
<value>true</value>
</element>
</value>
</property>
\endverbatim
<b> DataReaderQos </b>
Enable ZCSHMEM only for DataReaders that communicate using the \ndds zero-copy
over shared memory transport.
\verbatim
<property>
<value>
<element>
<name>dds.data_reader.type_plugin.disable_zcshmem</name>
<value>true</value>
</element>
</value>
</property>
\endverbatim
<b> Publishing Data </b>
\verbatim
MyType *sample;
MyTypeDataWriter *writer;
Create a DDS DomainParticipant, Publisher, and DataWriter and register MyType
as normal.
while (data_to_send) {
sample = MyTypeDataWriter_create_data(writer, DDS_BOOLEAN_TRUE);
if (sample == NULL) [
continue;
}
sample-> = ....;
MyTypeDataWriter_write(sample,....);
}
\endverbatim
<b> Subscribing to Data, Zero-Copy </b>
\verbatim
MyTypeDataReader *reader;
MyTypeSeq data_seq = = DDS_SEQUENCE_INITIALIZER;
DDS_SampleInfoSeq info_seg = DDS_SEQUENCE_INITIALIZER;
DDS_ReturnCode_t retcode;
Create a DDS DomainParticipant, Subscriber, and DataReader and register MyType
as normal.
while (data_to_receive) {
retcode = MyTypeDataReader_read/take(reader,&data_seq,&info_seq,.....);
if (retcode == DDS_RETCODE_OK) {
... process data ...
MyTypeDataReader_return_loan(reader,&data_seq,....);
}
}
\endverbatim
<b> Subscribing to Data, Copy </b>
\verbatim
MyType *sample;
MyTypeDataReader *reader;
MyTypeSeq data_seq = = DDS_SEQUENCE_INITIALIZER;
DDS_SampleInfoSeq info_seg = DDS_SEQUENCE_INITIALIZER;
DDS_ReturnCode_t retcode;
Create a DDS DomainParticipant, Subscriber, and DataReader and register MyType
as normal.
sample = MyTypeDataReader_create_data(reader, DDS_BOOLEAN_TRUE);
if (sample == NULL) {
... error ...
}
while (data_to_receive) {
retcode = MyTypeDataReader_read/take_next(reader,sample);
if (retcode == DDS_RETCODE_OK) {
... process ...
}
}
\endverbatim
*/
/*i \ingroup METPModuleAPI
*/
extern METPDllExport DDS_ReturnCode_t DDS_DataWriter_create_metp_data(
DDS_DataWriter *self,
void **sample,
DDS_Boolean *initialize_data);
/*i \ingroup METPModuleAPI
*/
extern METPDllExport DDS_ReturnCode_t
DDS_DataWriter_delete_metp_data(DDS_DataWriter *self, void *sample);
/*i \ingroup METPModuleAPI
*/
extern METPDllExport DDS_Boolean
DDS_DataWriter_is_metp_writer(DDS_DataWriter *self);
/*i \ingroup METPModuleAPI
*/
extern METPDllExport DDS_ReturnCode_t DDS_DataWriter_write_metp_data(
DDS_DataWriter *self,
const void *instance_data,
const DDS_InstanceHandle_t *handle,
struct DDS_WriteParams_t *w_params);
/*i \ingroup METPModuleAPI
*/
extern METPDllExport DDS_ReturnCode_t DDS_DataReader_is_metp_data_consistent(
DDS_DataReader *self,
DDS_Boolean *is_consistent,
const void *sample,
const struct DDS_SampleInfo *sample_info);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* metp_dds_h */