C# Bindings
C# bindings let your Rust library be used from .NET applications.
The template uses csbindgen to automatically generate .NET wrapper classes, handling cross-platform library loading and calling conventions so you can focus on writing Rust code.
The bindings are generated from the C Exports; with precompiled binaries for all supported CoreCLR platforms, including Windows, Linux and macOS.
Example Bindings
Generated C# Bindings (NativeMethods.g.cs)
// <auto-generated>
// This code is generated by csbindgen.
// DON'T CHANGE THIS DIRECTLY.
// </auto-generated>
#pragma warning disable CS8500
#pragma warning disable CS8981
using System;
using System.Runtime.InteropServices;
namespace prs_rs.Net.Sys;
public static unsafe partial class NativeMethods
{
const string __DllName = "prs_rs";
/// <summary>
/// Compresses the given data in `source`, placing it in `destimation`.
///
/// Parameters
///
/// - `src`: A pointer to the compressed data.
/// - `src_len`: Length of the compressed data.
/// - `destination`: A pointer to the decompressed data to be written.
///
/// # Returns
///
/// Number of bytes written to `destination`.
///
/// # Safety
///
/// It's safe as long as `dest` has sufficient length (max length: [`prs_calculate_max_compressed_size`])
/// and the remaining parameters are valid.
/// </summary>
[DllImport(__DllName, EntryPoint = "prs_compress", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern nuint prs_compress(byte* src, byte* dest, nuint src_len);
/// <summary>
/// Decompresses PRS compressed data, in an unsafe manner, without any error handling.
///
/// # Parameters
///
/// - `source`: A pointer to the compressed data.
/// - `destination`: A pointer to the decompressed data.
///
/// # Returns
///
/// - The length of the decompressed data.
///
/// # Safety
///
/// Function is safe as long as the source points to valid PRS compressed data with
/// a terminator byte. The destination should be large enough to store the decompressed data.
/// </summary>
[DllImport(__DllName, EntryPoint = "prs_decompress", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern nuint prs_decompress(byte* src, byte* dest);
}
The generated bindings include proper P/Invoke declarations with cross-platform calling conventions.
How to Export Functions
C# bindings are generated from C bindings, so the same export rules apply.
See C/C++ Bindings - How to Export Functions for detailed examples and best practices.
Automatic Binding Generation
Info
Your C# bindings are automatically generated and packaged when you build your project.
Generate bindings locally:
cd src
cargo build --features c-exports # Generate C# bindings and NuGet package
Bindings are placed in bindings/csharp/NativeMethods.g.cs.
When you build your project, bindings are generated with csbindgen and a NuGet package is created with precompiled binaries for all supported platforms. The package includes the generated P/Invoke declarations and native libraries for Windows, Linux, and macOS.
The NuGet package is automatically published to nuget.org when you create a release tag.
Version Management
Warning
C# NuGet package versions must be manually synchronized with Rust crate versions.
The C# NuGet package version in bindings/csharp/csharp.csproj is not automatically synchronized with your Rust crate version. When you release a new version:
- Update Rust Version: Bump the version in
Cargo.toml - Update C# Version: Manually update the
<Version>inbindings/csharp/csharp.csprojto match - Create Release Tag: Push a tag with the new version number
This is because there may be multiple projects in a single repo- with their own versions.
Integration with Existing Projects
Info
Add C# bindings to existing projects by copying configuration files from the template.
1. Generate Template Files
First, generate a fresh template to get the latest configuration files:
cargo generate --git https://github.com/Reloaded-Project/reloaded-templates-rust.git
2. Copy Configuration Files
Copy these key files from the generated template to your existing project:
bindings/csharp/NativeMethods.cs- DllImportResolver implementationbindings/csharp/Init.cs- Module initializerbindings/csharp/csharp.csproj- C# project configurationbindings/csharp/.gitignore- Version control rules- Relevant sections from
Cargo.tomlandbuild.rsfor csbindgen integration
3. Update Project Configuration
Add csbindgen to your build dependencies in Cargo.toml:
[build-dependencies]
csbindgen = "1.9.0"
Modify your build.rs to generate C# bindings:
fn main() {
csbindgen::Builder::default()
.input_extern_file("src/exports.rs")
.csharp_dll_name("your_library_name")
.csharp_class_accessibility("public")
.csharp_namespace("YourLibrary.Net.Sys")
.generate_csharp_file("../bindings/csharp/NativeMethods.g.cs")
.unwrap();
}
See the main documentation for more details on getting started with cargo-generate.