Subsystem · Language bindings

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

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 — 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

What we built

Eight bindings, one core. Each 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.97+.
cpp C++17 binding OMG DDS-PSM-Cxx 1.0 — spec-conformant C++17 PSM. ABI-stable headers emitted by zerodds-idlc generate --lang c++.
cs C# / .NET bindingVendor PSM. .NET 8, async/await, IDisposable lifetime, NuGet packages ZeroDDS, ZeroDDS.Cdr, ZeroDds.Wire.
java-omgdds Java binding OMG DDS-Java-PSM (org.omg.dds.*) — spec-conformant, Pure Java (no JNI) with its own RTPS stack. Maven org.zerodds:omgdds.
py Python binding Vendor PSM. PyO3 bindings for the DCPS API + typed topics from zerodds-idlc generate --lang python + AsyncIO wrapper. abi3 wheels for Python 3.9 and newer.
ts-node TypeScript (Node)Vendor PSM for Node.js. Full DCPS + WebSocket / gRPC bridge plumbing.
ts-wasmTypeScript (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
C++ PSM DDS-PSM-Cxx 1.0 C++ example → crates/cpp cpp/tests
Java PSM DDS-Java-PSM Java example → crates/java-omgdds java-omgdds/test
Rust PSM ZeroDDS vendor PSM → Rust example → crates/rs rs/tests
C# / .NET PSM ZeroDDS vendor PSM → C# example → crates/cs cs/tests
Python PSM ZeroDDS vendor PSM → Python example → crates/py py/python/tests
TypeScript PSM (Node) ZeroDDS vendor PSM → Node example → crates/ts-node ts-node/tests
TypeScript PSM (browser) ZeroDDS vendor PSM → Browser example → crates/ts-wasm ts-wasm/tests
C-FFI ZeroDDS C ABI → C example → crates/zerodds-c-api zerodds-c-api/tests
How

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.

Upgrade guide →

Per-language pointers

Rust

cargo add zerodds-dcps zerodds-rs. Async via dcps-async. The published 1.0.0-rc.7 crates need Rust 1.88+, a build from source Rust 1.97+.

cargo add zerodds-dcps zerodds-rs
C++

OMG DDS-PSM-Cxx 1.0. Headers emitted by zerodds-idlc generate --lang c++. CMake integration shipped.

find_package(ZeroDDS REQUIRED)
target_link_libraries(my_app ZeroDDS::dcps)
C# / .NET

dotnet add package ZeroDDS --prerelease. .NET 8+, async/await.

dotnet add package ZeroDDS --version 1.0.0-rc.7
Java

OMG DDS-Java-PSM (org.omg.dds.*). Pure Java — no JNI, no native lib.

<dependency>org.zerodds:omgdds:1.0.0-rc.7</dependency>
Python

PyO3 bindings for the DCPS API plus an AsyncIO wrapper; typed topics from zerodds-idlc generate --lang python. abi3 wheels for Python 3.9 and newer.

pip install zerodds
TypeScript

Two variants: Node.js (full DCPS + bridges) and browser bundle (WebSocket only).

npm install @zerodds/node@rc
C-FFI

Stable C ABI. Link with -lzerodds. Header pulls everything from libzerodds.so / zerodds.dll.

#include <zerodds.h>

Endpoint languages

Fourteen further languages carry an endpoint SDK under endpoints/ and no binding page yet. Their pages exist as scaffolds — source and example links only; no capability is stated until the thin-frontend capability matrix has been measured.

Endpoint-Sprachen

Vierzehn weitere Sprachen tragen unter endpoints/ ein Endpoint-SDK und haben noch keine Binding-Seite. Ihre Seiten stehen als Gerüst — nur Quell- und Beispiel-Links; solange die Fähigkeitsmatrix der Thin-Frontends nicht gemessen ist, steht dort keine Fähigkeitsaussage.