Language bindings
Seven native DCPS APIs, all driven by the same wire format. No JNI, no P/Invoke, no thin wrappers — each binding is a first-class crate.
Learn — what is a language binding (PSM)?
DDS is defined at two levels. The PIM — Platform-Independent Model — describes Participant, Topic, Publisher, Subscriber, DataWriter, DataReader as abstract concepts. The PSM — Platform-Specific Mapping — maps those concepts onto a concrete programming language: which class, which method signature, which threading model, which error type.
OMG has ratified PSMs for C++ (DDS-PSM-Cxx 1.0) and Java (DDS-Java-PSM). For C#, Python, TypeScript and Rust the industry uses vendor-defined PSMs — every vendor invents their own, which is why moving an application from one vendor to another usually means rewriting all the binding code.
ZeroDDS ships seven native PSMs in one workspace. The OMG-defined C++ and Java PSMs are spec-conform; the C#, Python, TypeScript, Rust and C-FFI PSMs are vendor PSMs documented as ZeroDDS extensions. All seven sit on the same Pure-Rust core — no JNI, no P/Invoke, no transitive C dependencies.
Why — why native bindings, not just one C-FFI?
The cheap option for a multi-language project is one C-FFI library plus thin wrappers in every other language. It compiles fast and looks clean from outside. The hidden cost shows up in production.
First, performance: every call across an FFI boundary serialises arguments, checks lifetimes, and pays a context-switch tax. For a hot-path DataWriter writing 10 kHz that is a measurable hit. Native bindings call directly into Rust functions with zero-cost type erasure.
Second, idiomatic surface: a Java developer expects @Override, AutoCloseable, virtual threads; a Python developer expects async-await, mypy-checkable types; a C# developer expects IDisposable, async/await with CancellationToken. A C-FFI wrapper can fake those — badly. A native binding renders them naturally.
Third, audit trail: when a Java auditor traces a security incident, they want to see Java source, not a JNI wrapper around an opaque C function. Native bindings make every layer auditable in the language of the consuming team.
Fourth, no JNI / no P/Invoke / no transitive C toolchain: ZeroDDS' Java is Pure Java (no native libraries), the C# is Pure C# (no DllImport). The whole binding compiles with the standard JDK / .NET SDK — no platform-specific .so / .dll to manage.
What we built
Eight binding crates, one core. Each crate is RC3-ready and ships with its own README, examples and spec-coverage report.
| Crate | Role | Spec / target |
|---|---|---|
dcps | Core PIM | OMG DDS 1.4 — the PIM that all language bindings sit on. Provides Participant, Publisher, Subscriber, Writer, Reader, QoS-Policy types. |
dcps-async | Async wrapper | Async/await flavour of the core. Tokio-compatible. Shared by Rust and C# bindings. |
rs | Rust binding | zerodds-rs — idiomatic Rust SDK, async/await, streams. Stable Rust 1.88+. |
cpp | C++17 binding | OMG DDS-PSM-Cxx 1.0 — spec-conformant C++17 PSM. ABI-stable headers emitted by zerodds-idlc --cpp. |
cs | C# / .NET binding | Vendor PSM. .NET 8 + netstandard2.1, async/await, IDisposable lifetime, NuGet-packageable. |
java-omgdds | Java binding | OMG DDS-Java-PSM (org.omg.dds.*) — spec-conformant, Pure Java (no JNI). Records, sealed types, virtual threads. |
py | Python binding | Vendor PSM. PyO3-Bindings für DCPS-API + @idl_struct-Decorator für Codegen-freien Topic-Pfad + AsyncIO-Wrapper. Wheels für CPython 3.8–3.14 (abi3-py38). |
ts-node | TypeScript (Node) | Vendor PSM for Node.js. Full DCPS + WebSocket / gRPC bridge plumbing. |
ts-wasm | TypeScript (browser) | Vendor PSM for browsers. WebSocket-only transport, no native sockets. Compiles to WASM. |
zerodds-c-api | C-FFI | Stable C ABI in zerodds-c-api. Header pulls in libzerodds.so / zerodds.dll. For languages we do not ship native bindings for. |
sys | FFI helpers | Internal FFI plumbing used by zerodds-c-api. Not consumed directly. |
Spec coverage — by PSM
Two OMG PSMs and six vendor PSMs. The OMG ones are spec-conformant end-to-end; the vendor ones follow ZeroDDS conventions documented per language.
| PSM | Spec | 5-Min Quickstart | Implementation | Tests | Status |
|---|---|---|---|---|---|
| C++ PSM | DDS-PSM-Cxx 1.0 | C++ example → | crates/cpp | cpp/tests | ✓ full |
| Java PSM | DDS-Java-PSM | Java example → | crates/java-omgdds | java-omgdds/test | ✓ full |
| Rust PSM | ZeroDDS vendor PSM → | Rust example → | crates/rs | rs/tests | ✓ RC3 |
| C# / .NET PSM | ZeroDDS vendor PSM → | C# example → | crates/cs | cs/tests | ✓ RC3 |
| Python PSM | ZeroDDS vendor PSM → | Python example → | crates/py | py/python/tests | ✓ RC3 |
| TypeScript PSM (Node) | ZeroDDS vendor PSM → | Node example → | crates/ts-node | ts-node/tests | ✓ RC3 |
| TypeScript PSM (browser) | ZeroDDS vendor PSM → | Browser example → | crates/ts-wasm | ts-wasm/tests | ✓ RC3 |
| C-FFI | ZeroDDS C ABI → | C example → | crates/zerodds-c-api | zerodds-c-api/tests | ✓ RC3 |
How — using the bindings
One install line per language, one or two-line ‘hello pub/sub’ example, links to the architecture doc and the man page.
ABI guarantees
Within a major version (1.x), wire-stable across every patch release. Source-stable within a minor (1.M.x). Breaking source changes only at major version boundaries (1 → 2). See the upgrade-guide topic for the matrix.
Per-language pointers
- Rust
-
cargo add zerodds-dcps zerodds-rs. Async via dcps-async. Stable Rust 1.88+.
cargo add zerodds-dcps zerodds-rs - C++
-
OMG DDS-PSM-Cxx 1.0. Headers emitted by zerodds-idlc --cpp. CMake integration shipped.
find_package(ZeroDDS REQUIRED) target_link_libraries(my_app ZeroDDS::dcps) - C# / .NET
-
dotnet add package ZeroDDS.Dcps. .NET 8+, netstandard2.1, async/await.
dotnet add package ZeroDDS.Dcps - Java
-
OMG DDS-Java-PSM (org.omg.dds.*). Pure Java — no JNI, no native lib.
<dependency>org.zerodds:dcps:1.0.0</dependency> - Python
-
PyO3-Bindings für die DCPS-API plus AsyncIO-Wrapper und @idl_struct-Decorator für Codegen-freien Topic-Pfad. Wheels für CPython 3.8–3.14 (abi3-py38).
pip install zerodds - TypeScript
-
Two variants: Node.js (full DCPS + bridges) and browser bundle (WebSocket only).
npm install @zerodds/dcps - C-FFI
-
Stable C ABI. Link with -lzerodds. Header pulls everything from libzerodds.so / zerodds.dll.
#include <zerodds.h>