NativeInvoke 1.3.1
dotnet add package NativeInvoke --version 1.3.1
NuGet\Install-Package NativeInvoke -Version 1.3.1
<PackageReference Include="NativeInvoke" Version="1.3.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="NativeInvoke" Version="1.3.1" />
<PackageReference Include="NativeInvoke"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add NativeInvoke --version 1.3.1
#r "nuget: NativeInvoke, 1.3.1"
#:package NativeInvoke@1.3.1
#addin nuget:?package=NativeInvoke&version=1.3.1
#tool nuget:?package=NativeInvoke&version=1.3.1

🌟 ᑎᗩTIᐯEIᑎᐯOKE ✨
High-performance, source-generated P/Invoke
NativeInvoke is a modern, zero-overhead, generics-capable P/Invoke generator for .NET.
It uses Roslyn source generation to enforce blittable, function-pointer based, lazy-loaded native bindings - without the runtime overhead of DllImport.
You write clean interfaces.
NativeInvoke generates the unsafe bits for you at compile-time.
- Cross-platform and AOT/JIT-friendly.
- No
DllImport. - No delegate allocation (no pinning).
- No runtime dependencies.
- No marshalling.
- No reflection.
- No dynamic codegen (dynamic IL).
- Just pure compile-time generation glue.
🚀 Quick Installation
Install the NuGet package:
dotnet add package NativeInvoke
Or edit your .csproj to always stay up-to-date (followed by dotnet restore --no-cache):
<ItemGroup>
<PackageReference Include="NativeInvoke" Version="*"/>
</ItemGroup>
How floating versions work:
*-*: Latest version including pre-releases (e.g.,1.1.0-beta.1,2.0.0-alpha.2)*: Latest stable version only1.*: Latest stable version with major version 11.2.*: Latest stable version with major.minor 1.2
🧠 Why NativeInvoke?
| Feature | Benefit |
|---|---|
| Source-generated | Zero runtime overhead |
| Function pointers | Faster than DllImport |
| Lazy-loading support | Load symbols/functions only when needed |
| Interface-based | Fully mockable for testing |
| Generics support | Use generics in P/Invoke |
| No static pollution | Clean public API surface |
.NET 9 Lock support |
Modern, allocation-free synchronization |
🛠 Requirements
- C# 14 / .NET 9 or later
- Unsafe code enabled (
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>) - Roslyn source generators enabled (default in SDK-style projects)
✨ Example Usage
Checkout the full Example project for more!
Here is slightly verbose example for playing a beep sound on Windows platform (a.k.a. System.Console.Beep):
1. Define your native interface
global using NativeInvoke; // Import our attributes in your project
global using NIMA = NativeInvoke.NativeImportMethodAttribute;
using BOOL = int; // Win32 BOOL is 4-bytes (0=false, 1=true)
using DWORD = uint; // double-word
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")] // Optional (for clarity)
#endif
public interface IKernel32<TBool> // Generics are supported!
where TBool : unmanaged
{
[NIMA("Beep")] // Optional; Use this attribute if you want to load a different name/ordinal,
// or override a calling convention per function (defaults to platform-specific).
TBool Boop(DWORD frequency, DWORD duration);
[NIMA(null)] // Use null or empty string to skip generation; could also omit this and set ExplicitOnly=true
void IgnoreMe();
}
2. Expose it via a static partial property
The property can be nested anywhere you want (class/struct/interface/record), and you can use any accessibility level you need - the generator will match your declaration.
public static partial class Win32
{
private const string kernel32 = "kernel32";
[NativeImport(
kernel32 // Specify native library name
, EnforceBlittable = true // Whether to enforce blittable type validation (applies to all methods, can be overriden per-method)
, ExplicitOnly = false // Whether only methods explicitly marked with NIMA should be considered
, Inherited = true // Whether to consider inherited interface methods
, Lazy = false // Whether to use lazy or eager module loading
, CallingConvention = CallingConvention.StdCall // Define the default calling convention (default is platform-specific, applies to all methods, can be overriden per-method)
, SuppressGCTransition = false // Whether to suppress the GC transition (applies to all methods, can be overriden per-method)
, SymbolPrefix = "" // Define common prefix (prepended to method name unless using explicit entry point)
, SymbolSuffix = "" // Define common suffix (appended to method name unless using explicit entry point)
)]
public static partial IKernel32<BOOL> Kernel32 { get; }
}
3. Call it like a normal .NET API
Win32.Kernel32.Boop(600u, 300u);
Under the hood, NativeInvoke generates:
- A nested sealed
__Implclass implementing your (generic) interface - Static (readonly) function pointer fields (
delegate* unmanaged) - Lazy or eager symbol resolution (
NativeLibrary) - A clean property implementation using the
fieldkeyword - Thread-safe lazy initialization using .NET 9
Locktype
All without touching your container type.
💡 Future/Experiments (ToDo list)
- Support C# 9 / .NET 5 and later via
#if; current source generator is relying on C# 14 features and .NET 9 API - Add support for loading symbol from numeric ordinal
-
Implement default symbol name prefix and suffix -
AddEnforceBlittableandExplicitOnlyflags - Switch to
[UnmanagedCallConv]/typeof(CallConv*)for future-proofed calling conventions (MemberFunction, Swift, etc.) - Use
IndentedTextWriterfor source-code generation -
AppendGuidto generated fields (to prevent name collisions for overloaded functions) - Make unit tests
- Auto-generate proper page for docs and examples (maybe use GitHub io page or wiki)
- Explore micro-optimization: IL weaver via
Fody, replace interface dispatch andDllImportcalls withcalli
🙏 Contributing
PRs, issues, and ideas are welcome.
NativeInvoke is built for developers who want maximum performance without sacrificing clean API design.
💖 Support
If you like this or you are using this in your project, consider:
- Becoming a ⭐
- Spreading the word
📄 License
MIT - do whatever you want, just don't blame me if you calli into oblivion.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.