Interop in C# (Arbeiten mit C/C++-Bibliotheken)
Lernen Sie Interop in C#, um mit C/C++-Bibliotheken zu arbeiten, einschließlich P/Invoke und unmanaged Code.
In .NET-Anwendungen ist es manchmal notwendig, bestehende C- oder C++-Bibliotheken zu nutzen.
Dies wird Interop (Interoperabilität) genannt.
Die C#-Sprache bietet mit dem DllImport-Attribut Zugriff auf unmanaged Code.
Auf diese Weise können leistungsstarke oder systemnahe Funktionen direkt aufgerufen werden.
Native Funktionen mit DllImport aufrufen
Unter Windows können Funktionen aus Systembibliotheken wie user32.dll oder kernel32.dll
direkt aus C#-Code aufgerufen werden. Dafür wird der Namespace System.Runtime.InteropServices verwendet.
using System;
using System.Runtime.InteropServices;
class Program
{
// Win32-API-Funktion importieren
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, int type);
static void Main()
{
MessageBox(IntPtr.Zero, "Hallo Interop!", "Interop-Beispiel", 0);
}
}
Hier wird die Win32-API-Funktion MessageBox aufgerufen.
Obwohl der Code in C# kompiliert wurde, wird tatsächlich nativer (C-)Code ausgeführt.
Eine in C geschriebene Funktion aufrufen
Man kann auch eine eigene C/C++-Bibliothek (z. B. mylib.dll) verwenden.
Zuerst wird auf der C-Seite eine Funktion definiert:
// mylib.c
__declspec(dllexport) int AddNumbers(int a, int b)
{
return a + b;
}
// Import auf der C#-Seite
using System.Runtime.InteropServices;
class NativeMethods
{
[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int AddNumbers(int x, int y);
}
class Program
{
static void Main()
{
int ergebnis = NativeMethods.AddNumbers(5, 7);
Console.WriteLine($"Summe: {ergebnis}");
}
}
In diesem Beispiel wird die in C geschriebene Funktion AddNumbers aus C# aufgerufen.
Die Parameter werden automatisch per Marshaling in den passenden Typ konvertiert.
Structs und Marshaling
C-Bibliotheken können nicht nur primitive Typen, sondern auch struct-Typen verwenden.
In diesem Fall muss auf der C#-Seite dieselbe Struktur mit dem StructLayout-Attribut definiert werden.
// C-Seite
typedef struct
{
int width;
int height;
} Size;
__declspec(dllexport) int CalcArea(Size s)
{
return s.width * s.height;
}
// C#-Seite
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
public int width;
public int height;
}
class NativeMethods
{
[DllImport("mylib.dll")]
public static extern int CalcArea(Size s);
}
class Program
{
static void Main()
{
var groesse = new Size { width = 10, height = 20 };
int flaeche = NativeMethods.CalcArea(groesse);
Console.WriteLine($"Fläche: {flaeche}");
}
}
Leistung und Sicherheit
- Interop-Aufrufe sind langsamer als normale C#-Methoden (Marshaling-Overhead).
- Fehler im unmanaged Code (Memory Leaks, Pointer-Fehler) können die Anwendung direkt zum Absturz bringen.
- Daher sollte es nur verwendet werden, wenn es wirklich notwendig ist.
TL;DR
- Interop: Ermöglicht den Zugriff auf C/C++-Bibliotheken aus C#.
- Native Funktionen werden mit dem
DllImport-Attribut aufgerufen. - Structs müssen mit
StructLayoutkorrekt abgebildet werden. - Es gibt Performance-Overhead, daher vorsichtig einsetzen.
Ähnliche Artikel
Ausnahmebehandlung in C# (try, catch, finally)
Erlernen Sie die Ausnahmebehandlung in C# mit try-, catch- und finally-Blöcken zur sicheren Fehlerverwaltung anhand von Beispielen.
Grundlegende Datentypen in C#
Grundlegende Datentypen in C#: numerisch, textbasiert, logisch, objektorientiert und nullable.
Structs in C# – Unterschiede zu Klassen
Erfahren Sie die Unterschiede zwischen Structs und Klassen in C# in Bezug auf Speicher, Vererbung und Performance.
Typumwandlungen in C#
Erlernen Sie Typumwandlungen in C#, einschließlich impliziter und expliziter Konvertierung sowie Parse-, TryParse- und Convert-Methoden.