C sharp - Native Interoperability in C# (P/Invoke & COM Interop)
C# runs on the .NET runtime, which is managed code.
But sometimes you must interact with unmanaged code such as:
-
Windows API (Win32)
-
C/C++ DLLs
-
Legacy COM components
-
Hardware drivers
This interaction is called Interoperability (Interop).
There are two main mechanisms:
-
P/Invoke (Platform Invocation)
-
COM Interop
Part 1: P/Invoke (Platform Invocation)
What is P/Invoke?
P/Invoke allows C# to call functions inside native DLLs.
It is used when:
-
You need low-level OS functionality
-
You want to use existing C/C++ libraries
-
You need performance-critical native code
1. Basic Example (Calling Windows API)
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd,
string text,
string caption,
uint type);
static void Main()
{
MessageBox(IntPtr.Zero, "Hello", "Title", 0);
}
}
Explanation:
-
DllImporttells C# which DLL contains the function. -
externmeans implementation is outside .NET. -
The function executes inside unmanaged Windows code.
2. Important Concepts in P/Invoke
1. Marshaling
Managed and unmanaged memory formats differ.
Marshaling converts:
-
C# types → Native types
-
Native types → C# types
Example:
-
C#
string→ C-stylechar*
You can control marshaling:
[DllImport("SomeNative.dll")]
public static extern void Function(
[MarshalAs(UnmanagedType.LPStr)] string text);
2. Struct Layout
When passing structs:
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
public int A;
public double B;
}
Without correct layout:
-
Memory mismatch occurs
-
Application may crash
3. Calling Convention
Native functions use different calling conventions:
[DllImport("SomeDll.dll",
CallingConvention = CallingConvention.Cdecl)]
Wrong convention → stack corruption.
3. When to Use P/Invoke
-
Access Windows system APIs
-
Interact with device drivers
-
Use performance-critical C libraries
-
Interact with legacy native systems
Part 2: COM Interop
What is COM?
COM = Component Object Model
It is an older Microsoft technology for software components.
Used heavily in:
-
Microsoft Office automation
-
Legacy enterprise systems
-
Windows components
1. Example: Using Excel from C#
using Excel = Microsoft.Office.Interop.Excel;
class Program
{
static void Main()
{
var excelApp = new Excel.Application();
excelApp.Visible = true;
var workbook = excelApp.Workbooks.Add();
}
}
Here:
-
C# interacts with Excel COM object.
-
Excel is unmanaged code.
2. Runtime Callable Wrapper (RCW)
When C# uses a COM object:
-
.NET creates an RCW
-
RCW converts managed calls to COM calls
-
Handles reference counting
3. COM Object Cleanup
Unlike .NET garbage collection, COM uses reference counting.
So you must release manually:
Marshal.ReleaseComObject(excelApp);
Otherwise:
-
Memory leaks occur
-
Excel may remain in background
Managed vs Unmanaged Memory
| Managed (.NET) | Unmanaged |
|---|---|
| Garbage collected | Manual memory management |
| Type-safe | Less safe |
| CLR controlled | OS controlled |
Interop bridges these two worlds.
Risks of Interop
-
Memory leaks
-
Crashes
-
Security vulnerabilities
-
Performance overhead
-
Platform dependency
Interop should be used only when necessary.
Performance Consideration
Calling unmanaged code has overhead:
-
Marshaling cost
-
Context switching
-
Boundary crossing
Avoid frequent small calls.
Prefer batching operations.
Real-World Use Cases
-
Game engines using C++ physics libraries
-
Image processing libraries
-
Financial trading systems
-
Hardware communication