According to Wikipedia, LanguageInteroperability is the ability of two different programming languages to interact natively as part of the same system and to work on the same types of data structures.
This project shows simple examples in .Net for interoperability between C, C++, and C#, including:
- P/Invoke
- LibraryImport
- NativeAOT
The goal is also to demonstrate how managed C# code can be compiled as a native library and then called from native programs (focus on NativeAOT).
The project is deliberately kept minimal and serves as a technical reference for developers who want to link C and C# code via NativeAOT without using Visual Studio.
- Goal of the project
- Project structure (folder overview)
- Quickstart (Windows & Linux)
- Architecture Overview (C ↔ C# NativeAOT)
- Which Technique for What
- Code Examples
- Troubleshooting
- License Contributions
- Summary
Net-Language-Interoperability/
│
├── Docs/
├── Src/
│ ├── NativeLibrary/
│ ├── TestNativeLibrary/
│ ├── NativeLibraryLib/
│ └── TestLanguageInteroperability/
│ └── LanguageInteroperability/
│
└── Build/
└── Bin/
└── Native/
git clone https://github.com/michelenatale/Net-Language-Interoperability.git
cd Net-Language-InteroperabilityPublishing the NativeLibrary project via NativeAOT Build (Windows)
dotnet publish Src/NativeLibrary -c Release -r win-x64Publishing NativeLibrary via NativeAOT Build (Linux)
dotnet publish Src/NativeLibrary -c Release -r linux-x64dotnet build -c ReleaseFor the TestLanguageInteroperability, LanguageInteroperability, and NativeLibrary projects.
C/C++ build (Windows, MSVC)
cl Src\TestNativeLibrary\main.cC/C++ build (Linux, GCC)
gcc Src\TestNativeLibrary/main.c -o TestNativeLibraryThe same applies to the NativeLibraryLib project.
MSBuild.exe BuildAll.proj +------------------------------+
| TestLanguageInteroperability |
| (C#) |
|------------------------------|
| - P/Invoke |
| - LibraryImport |
| - NativeAOT (C# → C) |
+---------------+--------------+
|
| C# → C
v
+---------------------------+
| Native C Libraries |
| (crandom.dll / .so) |
+---------------------------+
^
| C → C#
|
+---------------------------+
| NativeLibrary (C#) |
| NativeAOT DLL/.lib |
| exportiert Funktionen |
+---------------------------+
^
| C → C#
|
+---------------------------+
| TestNativeLibrary |
| (C) |
| ruft NativeAOT‑Exports |
+---------------------------+
| Technique | Direction | Advantages | Typical Use |
|---|---|---|---|
P/Invoke (DllImport) |
C# → C | Simple, established, widely supported | Calling existing C APIs, Win32 |
| LibraryImport (Source Generator) | C# → C | Faster, compile‑time validation, less overhead | High‑performance interop |
| NativeAOT (C# → native DLL/.so) | C# → C | C# compiled to real native code | When C/C++ must call C# |
| NativeAOT + .lib Export | C → C# | C compiler links against C# code | Integrating .NET into native apps |
| C‑Wrapper → C# | C# → C → C# | Full ABI control | Complex or cross‑platform interop |
[DllImport("crandom.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void fill_random(byte[] buffer, int length);
var data = new byte[16];
fill_random(data, data.Length);[LibraryImport("crandom.dll")]
private static partial void fill_random_lib_import(Span<byte> buffer, int length);
Span<byte> data = stackalloc byte[16];
fill_random_lib_import(data, data.Length);[UnmanagedCallersOnly(EntryPoint = "aot_add")]
public static int Add(int a, int b) => a + b;#include <stdio.h>
__declspec(dllimport) int aot_add(int a, int b);
int main() {
printf("Result: %d\n", aot_add(3, 4));
return 0;
}- DllNotFoundException → DLL not in output folder
- BadImageFormatException → x86/x64 mismatch
- Use
dumpbin /headersto check architecture - Use
Path.Combineand MSBuild macros for paths
See LICENSE.
Contributions welcome.
This repository provides a compact, practical set of examples demonstrating the three major approaches to .NET ↔ native interoperability:
- P/Invoke
- LibraryImport
- NativeAOT
The structure is designed to make the mechanisms easy to understand and reuse in your own projects.