Unmanaged DLL per P/Invoke importieren

Funktionsimport in eine Klasse einbinden

public partial class MyClass
{
        // Funktion _Initialize() aus mytest.dll importieren
        // C/C++: int _Initialize(char *cpFileName);
        [DllImport("mytest.dll", EntryPoint="_Initialize", ExactSpelling=false, CallingConvention=CallingConvention.Cdecl)]
        private static extern int _Initialize(string sFileName);

        // Funktion _Add() aus mytest.dll importieren
        // C/C++: int _Add(int a, int b);
        [DllImport("mytest.dll", EntryPoint="_Add", ExactSpelling=false, CallingConvention=CallingConvention.Cdecl)]
        private static extern int _Add(int a, int b);

        public int Initialize(string sFileName)
        {
            return _Initialize(sFileName);
        }

        public int Add(int a, int b)
        {           
            return _Add(a, b);
        }
}

// Aufruf der DLLFunktion über das Objekt
MyClass DLLObject = new MyClass();
int iResult = DLLObject.Initialize("test.ini");
int iSum = DLLObject.Add(1, 2);

besondere Typen (z.B. structe) übergeben

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

public partial class Win32ImportClass
{
        // in C/C++
        // RECT rc;
        // HWND hwnd = FindWindow("main", NULL);
        // ::GetWindowRect(hwnd, &rc);

        [DllImport("user32.dll")]
        public static extern int GetWindowRect(int hwnd, ref RECT rc);
        // bei Klassenstrukturen anstelle von Structen -> Marshallen:
        // public static extern int GetWindowRect(int hwnd, [MarshalAs(UnmanagedType.LPStruct)] RECT rc);
}

// Anwendung
RECT rc = new RECT();
int hwnd = // hier noch das Handle holen ...
Win32ImportClass.GetWindowRect(hwnd, ref rc);

Hinweis

Sobald das Hostprojekt mit Plattformtyp “AnyCPU” compiliert wird, wird diese auf einem 64Bit-System (z.B. Windows 7 64Bit) auch als 64Bit-Anwendung ausgeführt. Wird nun auf diesem 64Bit-System eine 32Bit unmanaged DLL in die 64Bit-Hostanwendung geladen, führt dies zu einer System.BadImageFormatException. Es gibt zwei Möglichkeiten dies zu umgehen:

  1. Hostanwendung als Plattformtyp “x86” (32Bit) kompilieren (Projekt->Eigenschaften->Erstellen->Zielplattform->x86), so dass auch unter einem 64Bit-System die Anwendung zwangsweise als 32Bit ausgeführt wird
  2. oder die DLL zu einer 64Bit DLL umwandeln und kompilieren

Links