RocksDB-Sharp

Native interop

RocksDB-Sharp is a managed wrapper around the C ABI exposed by RocksDB (include/rocksdb/c.h). This page covers how the native binary is located and loaded at runtime, and how to call into the raw C API when you need a function that the high-level binding doesn't expose yet.


How the native binary is loaded

The NuGet package ships precompiled binaries inside runtimes/<rid>/native/:

runtimes/
├── win-x64/native/rocksdb.dll
├── linux-x64/native/librocksdb.so
├── linux-arm64/native/librocksdb.so
├── osx-x64/native/librocksdb.dylib
└── osx-arm64/native/librocksdb.dylib

At runtime, the AutoNativeImport helper (declared in Native.Load.cs / AutoNativeImport.cs) picks the right file for the current RuntimeInformation.RuntimeIdentifier and loads it via NativeLibrary.Load (or the equivalent on older runtimes). You don't need to do anything to make this work — the first call into Native.Instance triggers the load.

If you publish your app:

  • Framework-dependent (dotnet publish): the runtimes folder is copied next to your binary. Works out of the box.
  • Self-contained (dotnet publish -r <rid>): the right RID-specific binary is included in the output. Works out of the box.
  • Single-file (PublishSingleFile=true): add <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract> to your csproj so the native binary is extracted at startup.
Custom load locations

If you need to load the native binary from a non-standard place — embedded as a resource, on a special disk, etc. — you can take ownership of the load before any call into Native.Instance. See Native.Load.cs for the helper hooks.


Calling the raw C API

Every function in rocksdb_c.h is declared on Native (see Native.cs). The mid-level layer (Native.Wrap.cs / Native.Marshaled.cs) wraps most of them in friendlier signatures.

using RocksDbSharp;

using var db = RocksDb.Open(new DbOptions().SetCreateIfMissing(true), path);

// Mid-level — use the wrapped function:
ulong seq = Native.Instance.rocksdb_get_latest_sequence_number(db.Handle);

For low-level calls that take an errptr, you handle marshalling yourself:

unsafe
{
    IntPtr err;
    UIntPtr keylen = (UIntPtr)key.Length;
    IntPtr valuePtr = Native.Instance.rocksdb_get(
        db.Handle,
        ReadOptions.Default.Handle,
        key,
        keylen,
        out UIntPtr valueLength,
        out err);

    if (err != IntPtr.Zero)
    {
        string message = Marshal.PtrToStringAnsi(err);
        Native.Instance.rocksdb_free(err);
        throw new RocksDbException(message);
    }

    // Use the value, then free it:
    Native.Instance.rocksdb_free(valuePtr);
}

The high-level db.Get(...) does exactly this for you.


Mixing layers

Every high-level type (RocksDb, Iterator, WriteBatch, Snapshot, …) exposes its underlying IntPtr Handle. You can hand those into a low-level call and mix freely:

using var db    = RocksDb.Open(options, path);
using var batch = new WriteBatch();

batch.Put("k", "v");

// Drop down for a per-write option that isn't on WriteOptions yet:
var wo = Native.Instance.rocksdb_writeoptions_create();
try
{
    Native.Instance.rocksdb_write(db.Handle, wo, batch.Handle);
}
finally
{
    Native.Instance.rocksdb_writeoptions_destroy(wo);
}
Handle ownership

The high-level types call *_destroy in their Dispose. Don't destroy their handles yourself, and don't Dispose them while you're still using their Handle via the low-level API.


Exception model

The high-level API throws:

  • RocksDbException — wraps RocksDB's own error messages (the errptr strings).
  • RocksDbSharpException — binding-side errors (e.g. attempting CF operations on a DB opened without column families).
  • DllNotFoundException — the native binary couldn't be located at runtime. See Installation troubleshooting.

Building from source

If you want to build the native binary yourself (e.g. for a custom architecture, or to apply a patch), see build-native/ and build-codegen/ in the main repository. The repository's Azure Pipelines build script rebuilds the native binaries on every official RocksDB release.

© 2026 RocksDB-Sharp. All rights reserved.