SciSharp /
TensorFlow.NET
.NET Standard bindings for Google's TensorFlow for developing, training and deploying Machine Learning models in C# and F#.
86/100 healthLoading repository data…
pjanec / repository
.NET C# bindings for cyclone dds, code-first, high performance, zero-allocation
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A modern, high-performance, zero-allocation .NET binding for Eclipse Cyclone DDS, with idiomatic C# API.
See detailed technical overview.
Install the CycloneDDS.NET package from NuGet:
dotnet add package CycloneDDS.NET
This single package includes:
net8.0; runs on .NET 8 and later).ddsc.dll, idlc.exe) and Linux x64 (libddsc.so, idlc). NuGet selects the correct runtime asset per platform automatically.| Platform | Native runtime | Target requirement |
|---|---|---|
| Windows x64 | ddsc.dll | Visual C++ Redistributable for Visual Studio 2022 installed on the target machine. |
| Linux x64 | libddsc.so | A glibc-based distribution (e.g. Ubuntu/Debian). No extra runtime install needed. |
If you want to build the project from source or contribute:
Clone the repository (recursively, to get the native submodule):
git clone --recursive https://github.com/pjanec/CycloneDds.NET.git
cd CycloneDds.NET
Build the native libraries for your platform:
.\build\native-win.ps1build/native-linux.sh ReleaseThen build and test the managed solution:
dotnet build CycloneDDS.NET.Core.slnf -c Release
dotnet test CycloneDDS.NET.Core.slnf -c Release
On Windows you can instead run the one-stop script .\build\build-and-test.ps1, which builds the native artifacts (if missing), builds the solution, and runs the tests.
Requirements:
net8.0, but building requires the .NET 10 SDK (the code uses C# 13 language features). Produced binaries still run on .NET 8+.PATH.patchelf — e.g. sudo apt-get install -y cmake build-essential patchelf.ref struct views, bypassing deserialization..Data.[DdsTopic], [DdsKey], [DdsStruct], [DdsQos]). No need to write IDL files manually.[InlineArray] (safe fixed-size arrays without unsafe), typed enums (enum E : byte emits @bit_bound(8)), and default topic naming based on namespaces.IdlImporter tool.WaitDataAsync for non-blocking, task-based consumers.view => view.Id > 5) compiled to JIT code.DdsWaitSet.Wait(Span<IDdsReader>, timeout, ct) never allocates in the hot path and supports CancellationToken for instant, safe interruption.Define your data using standard C# partial structs. The build tools generate the serialization logic automatically.
Use this for high-frequency data (1kHz+).
using CycloneDDS.Schema;
namespace Factory.Monitoring;
// Topic name defaults to namespace + class name ("Factory_Monitoring_SensorData") if omitted
[DdsTopic]
public partial struct SensorData
{
[DdsKey, DdsId(0)]
public int SensorId;
[DdsId(1)]
public double Value;
// Fixed-size buffer (maps to char[32]). No heap allocation.
[DdsId(2)]
public FixedString32 LocationId;
// Safe, zero-allocation fixed array using C# 12 [InlineArray] (no 'unsafe' needed!)
[DdsId(3)]
public FloatBuffer8 Measurements;
// Byte-backed enum yields IDL @bit_bound(8) automatically for optimal native network usage
[DdsId(4)]
public SensorStatus Status;
}
[System.Runtime.CompilerServices.InlineArray(8)]
public struct FloatBuffer8 { private float _element0; }
public enum SensorStatus : byte
{
Offline,
Online,
Error
}
For scenarios requiring direct memory manipulation or porting legacy C/C++ structs, you can use unsafe fixed arrays. The runtime maps these directly to native memory with zero allocation.
[DdsTopic("CustomTopicNameForVideoFrame")]
public unsafe partial struct VideoFrame
{
[DdsKey]
public int FrameId;
// Classic C# unsafe fixed-size buffer
public fixed byte Pixels[1920 * 1080 * 3];
}
Use this for business logic where convenience outweighs raw speed.
[DdsStruct] // Helper struct to be used in the topic data struct (can be nested)
public partial struct GeoPoint { public double Lat; public double Lon; }
[DdsTopic("LogEvents")]
[DdsManaged] // Opt-in to GC allocations for the whole type
public partial struct LogEvent
{
[DdsKey]
public int Id;
// Standard string (Heap allocated)
public string Message;
// Standard List (Heap allocated)
public List<double> History;
// Nested custom struct
public GeoPoint Origin;
}
You can define Quality of Service settings directly on the type using the [DdsQos] attribute. The Runtime automatically applies these settings when creating Writers and Readers for this topic.
[DdsTopic("MachineState")]
[DdsQos(
Reliability = DdsReliability.Reliable, // Guarantee delivery
Durability = DdsDurability.TransientLocal, // Late joiners get the last value
HistoryKind = DdsHistoryKind.KeepLast, // Keep only recent data
HistoryDepth = 1 // Only the latest sample
)]
public partial struct MachineState
{
[DdsKey]
public int MachineId;
public StateEnum CurrentState;
}
using Factory.Monitoring;
using var participant = new DdsParticipant();
// Auto-discovers topic type and its default name ("Factory_Monitoring_SensorData")
using var writer = new DdsWriter<SensorData>(participant);
// Zero-allocation write path
var data = new SensorData
{
SensorId = 1,
Value = 25.5,
LocationId = new FixedString32("Factory_A"),
Status = SensorStatus.Online
};
// With C# 12, InlineArrays can be accessed directly by index
data.Measurements[0] = 1.0f;
writer.Write(data);
Reading uses a Scope pattern to ensure safety and zero-copy semantics. You "loan" the data, read it, and return it by disposing the scope.
using Factory.Monitoring;
using var reader = new DdsReader<SensorData>(participant);
// POLL FOR DATA
// Returns a "Loan" which manages native memory
using var loan = reader.Take(maxSamples: 10);
// Iterate received data
foreach (var sample in loan)
{
// `sample.IsValid` indicates whether a full payload is present.
// IMPORTANT: even when `ValidData == 0` (lifecycle/metadata-only samples),
// the middleware provides the native memory with the topic key fields populated.
// Therefore `sample.Data` is safe to call for every sample and will return
// a managed object where key fields are set and non-key fields are defaulted.
// Always obtain the managed copy (safe for metadata-only samples too)
var data = sample.Data;
if (sample.IsValid)
{
// OPTION A: Simple (Managed)
// `data` is a full managed copy populated from native memory
Console.WriteLine($"Received: {data.SensorId} = {data.Value}");
}
else
{
// Lifecycle event (e.g., instance disposed). Key fields are available in `data`.
Console.WriteLine($"Instance {data.SensorId} state: {sample.Info.InstanceState}");
}
// OPTION B: Fast (Zero-Copy) — you can still use AsView() when you only need
// transient, zero-allocation access to the native buffer (stack-only).
// var view = sample.AsView();
}
Bridge the gap between real-time DDS and .NET Tasks. No blocking threads required.
Console.WriteLine("Waiting for data...");
// Efficiently waits using TaskCompletionSource (no polling loop)
while (await reader.WaitDataAsync())
{
// Take all available data
using var scope = reader.Take();
foreach (var sample in scope)
{
await ProcessAsync(sample);
}
}
Filter data before you pay the cost of processing it. This implementation uses C# delegates but executes on the raw buffer view, allowing JIT optimizations to make it extremely fast.
// 1. Set a filter predicate on the Reader
// Logic executes during iteration, skipping irrelevant samples instantly.
// Since 'view' is a ref struct reading raw memory, this is Zero-Copy filtering.
reader.SetFilter(view => view.Value > 100.0 && view.LocationId.ToString() == "Lab_1");
// 2. Iterate
using var scope = reader.Take();
foreach (var highValueSample in scope)
{
// Guaranteed to be > 100.0 and from Lab_1
}
// 3. Update filter dynamically at runtime
reader.SetFilter(null); // Clear filter
For systems tracking many objects (fleets, tracks, sensors), efficiently query a specific object's history without iterating the entire database.
// 1. Create a key template for the object we care about
var key = new SensorData { SensorId = 5 };
// 2. Lookup the Handle (O(1) hashing)
DdsInstanceHandle handle = reader.LookupInstance(key);
if (!handle.IsNil)
{
// 3. Read history for ONLY Sensor 5
// Ignores Sensor 1, 2, 3... Ze
Selected from shared topics, language and repository description—not editorial ratings.
SciSharp /
.NET Standard bindings for Google's TensorFlow for developing, training and deploying Machine Learning models in C# and F#.
86/100 healthdotnet /
.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
68/100 healthdotnet /
.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
Ruslan-B /
FFmpeg auto generated unsafe bindings for C#/.NET and Core (Linux, MacOS and Mono).
89/100 healthsdcb /
.NET/C# binding for Baidu paddle inference library and PaddleOCR
77/100 healthdotnet /
Clang bindings for .NET written in C#
84/100 health