DDS Abstraction Bindings
The DDS Abstraction Layer is a header-only C++20 library that provides a portable publish/subscribe API across multiple DDS vendors. Write your application once and switch DDS middleware at compile time — no source changes required.
Supported Backends
| Define | Backend |
|---|---|
LDM_ASTUTE |
AstuteDDS |
LDM_CYCLONE |
Eclipse CycloneDDS |
LDM_RTI |
RTI Connext DDS |
LDM_OSPL |
OpenSplice DDS |
Installing from the Release Tarball
Every tagged release of AstuteDDS attaches a portable bindings tarball:
astutedds-bindings-<version>.tar.gz
Download it from the GitHub Releases page.
Extract
tar -xzf astutedds-bindings-<version>.tar.gz
This produces a directory tree:
astutedds-bindings-<version>/
├── dds_abstraction/
│ ├── CMakeLists.txt
│ ├── README.md
│ ├── include/
│ │ └── dds_abstraction/
│ │ ├── dds_abstraction.hpp
│ │ ├── dds_publisher.hpp
│ │ ├── dds_subscriber.hpp
│ │ ├── message_pattern.hpp
│ │ └── ...
│ └── examples/
│ ├── hello_world/
│ └── sensor/
├── rust/
└── LICENSE
Integrate with CMake
Point your project at the extracted directory and link the interface library:
# In your top-level CMakeLists.txt
add_subdirectory(path/to/astutedds-bindings-<version>/dds_abstraction)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE astutedds::dds_abstraction)
Note
Because the abstraction layer is header-only, no pre-built binaries are
needed. You only need the AstuteDDS SDK installed when compiling with the
LDM_ASTUTE backend.
Select a Backend
Define one of the backend macros before including the header:
#define LDM_ASTUTE
#include <dds_abstraction/dds_abstraction.hpp>
Or pass it via CMake:
target_compile_definitions(my_app PRIVATE LDM_ASTUTE)
Quick Start
Publisher
#define LDM_ASTUTE
#include <dds_abstraction/dds_abstraction.hpp>
using namespace astutedds::pubsub;
int main()
{
LdmPublisher<ShapeType> pub(0, "Square", MessagePattern::State);
pub.open();
ShapeType sample{};
sample.color("BLUE");
sample.x(100);
sample.y(200);
sample.shapesize(30);
pub.publish(sample);
pub.close();
return 0;
}
Subscriber
#define LDM_ASTUTE
#include <dds_abstraction/dds_abstraction.hpp>
using namespace astutedds::pubsub;
class MyListener : public SubscriberListener<ShapeType>
{
void on_data_received(ShapeType sample, dds::sub::SampleInfo info) override
{
std::cout << "Received: " << sample.color() << "\n";
}
};
int main()
{
MyListener listener;
LdmSubscriber<ShapeType> sub(0, "Square", MessagePattern::State);
sub.add_listener(&listener);
sub.open();
std::this_thread::sleep_for(std::chrono::seconds(30));
sub.close();
return 0;
}
GVA QoS Patterns
The MessagePattern enum maps to QoS policies per GVA Standards v2.1:
| Pattern | Durability | Reliability | History |
|---|---|---|---|
| State | TransientLocal | Reliable | KeepLast(256) |
| Specification | TransientLocal | Reliable | KeepLast(64) |
| Command | Volatile | Reliable | KeepLast(256) |
| Alarm | TransientLocal | Reliable | KeepLast(256) |
| Logging | Volatile | BestEffort | KeepLast(256) |
| Sotas | Transient | Reliable | (default) |
Topic-to-Pattern Inference
pattern_for_topic(std::string_view topic) automatically infers the correct
QoS pattern from a GVA topic name using suffix heuristics and a hard-coded
override table for Display Extension state-establishing commands.
Type Compatibility Macros
dds_compat.hpp provides macros (DDS_GET_FIELD, DDS_SET_FIELD, etc.)
that abstract accessor-style differences between RTI (direct field assignment)
and CycloneDDS/AstuteDDS (getter/setter methods).
Bundled Examples
The tarball includes ready-to-build examples:
| Example | Description |
|---|---|
hello_world |
Minimal publisher and subscriber pair |
sensor |
Sensor telemetry with listener callbacks |
Build them with:
cd astutedds-bindings-<version>/dds_abstraction/examples
mkdir build && cd build
cmake .. -DCMAKE_PREFIX_PATH=/usr/local
make -j$(nproc)