9 Stimmen

Dllimport programmatisch in C# einstellen

Ich verwende DllImport in meiner Lösung.
Mein Problem ist, dass ich zwei Versionen der gleichen DLL eine für 32 Bit und eine andere für 64 Bit gebaut haben.

Beide stellen die gleichen Funktionen mit identischen Namen und identischen Signaturen zur Verfügung. Mein Problem ist, dass ich zwei statische Methoden verwenden muss, die diese exponieren und dann zur Laufzeit verwenden IntPtr Größe, um den richtigen Aufruf zu ermitteln.

private static class Ccf_32
{
    [DllImport(myDllName32)]
    public static extern int func1();
}

private static class Ccf_64
{
    [DllImport(myDllName64)]
    public static extern int func1();
}

Ich muss dies tun, weil myDllName32 y myDllName64 muss konstant sein, und ich habe keine Möglichkeit gefunden, sie zur Laufzeit zu setzen.

Hat jemand eine elegante Lösung für diese so könnte ich loswerden der Code-Duplikation und die konstante IntPtr Größenkontrolle.

Wenn ich den Dateinamen festlegen könnte, bräuchte ich nur einmal zu prüfen, und ich könnte eine Menge wiederholten Code loswerden.

0 Stimmen

Es macht keinen Sinn, sie zur Laufzeit auszuwählen, wenn der Unterschied in der gesamten Kompilierung besteht.

1voto

GSerjo Punkte 4681

Können Sie zwei Methoden erstellen und eine davon zur Laufzeit auswählen, so dass Sie die Any CPU

public static class Ccf
{
    [DllImport(myDllName32)]
    private static extern int func32();

    [DllImport(myDllName64)]
    private static extern int func64();

    public static int func()
    {
        if(Environment.Is64BitProcess)
        {
            return func64();
        }
        return func32();
    }

}

0voto

Scott Dorman Punkte 41206

Sie können das nicht so machen, wie Sie wollen. Sie müssen an die DllImport Attribut als Metadaten, die zur Kompilierzeit verwendet werden. Infolgedessen können Sie die DLL, die sie dynamisch importiert, nicht ändern.

Wenn Sie Ihren verwalteten Code auf "Any CPU" ausrichten möchten, müssen Sie entweder die 32-Bit- und die 64-Bit-Bibliotheken als zwei verschiedene Funktionen importieren, die Sie je nach Laufzeitumgebung aufrufen können, oder einige zusätzliche Win32-API-Aufrufe verwenden, um die korrekte Version der nicht verwalteten Assembly zur Laufzeit zu laden, und zusätzliche Win32-Aufrufe zur Ausführung der erforderlichen Methoden. Der Nachteil dabei ist, dass Sie keine Kompilierzeitunterstützung für diese Art von Code für Typsicherheit usw. haben.

0voto

Brent Scriver Punkte 1

Hmm, ich frage mich, ob Sie eine Schnittstelle und dann eine Klasse mit den Methoden auf der Grundlage der 32-Bit- und 64-Bit-DLLs erstellen könnten.

Ich bin nicht sicher, ob es eine explizite Methode gibt, um festzustellen, ob Sie 64 Bit ausführen, aber Folgendes könnte funktionieren: Erlauben Sie unsicheren Code und haben Sie eine unsichere Funktion, die einen Zeiger auf eine Adresse erhält und dann feststellt, ob der Zeiger 4 oder 8 Byte groß ist. Anhand des Ergebnisses bestimmen Sie, welche Implementierung der Schnittstelle zu erstellen ist.

0voto

Robert Giesecke Punkte 4256

Sie können feststellen, ob Sie 64Bits ausführen oder nicht, indem Sie die Größe des IntPtr-Typs überprüfen (der ohnehin als native int bezeichnet wird). Dann können Sie die entsprechende DLL mit einem importierten LoadLibraryW-Aufruf laden, den Funktionszeiger mit GetProcAddress ermitteln und dann die Marshal.GetDelegateForFunctionPointer

Dies ist nicht annähernd so kompliziert, wie es aussehen mag. Sie müssen DllImport sowohl LoadLibraryW und GetProcAddress.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X