c++ - einbinden - Ermitteln Sie den geladenen Pfad für DLLs



visual studio 2017 dll einbinden (2)

Ich möchte meine Bewerbung in der folgenden Struktur haben.

Exe
 |
 |----- DLL\DLL.dll, DLL\common.dll 
 |
 |----- DLL2\DLL2.dll, DLL2\common.dll

Meine EXE lädt die DLLs durch

LoadLibraryEx(_T("DLL\\DLL.dll"), 0, 0);
LoadLibraryEx(_T("DLL2\\DLL2.dll"), 0, 0);

DLL.dll und DLL2.dll Projekt wird gegen common.dll durch lib-Datei common.dll . Es wird jedoch zwei verschiedene Versionen von common.dll .

Während der Ausführung erwartete Exe dass ich das Verzeichnis common.dll wie Exe common.dll , aber nicht dasselbe Verzeichnis wie DLL und DLL2 . Gibt es eine Möglichkeit, dies zu lösen, indem ich die obige Verzeichnisstruktur haben kann. Dennoch, benutze immer noch lib, um DLL/DLL2 mit common zu verlinken.

https://ffff65535.com


  1. Sie möchten zwei verschiedene DLLs mit demselben Name (common.dll) in demselben Prozess laden.

    Das scheint mir eine schlechte Idee zu sein. Ist es wirklich notwendig? Kann einer von ihnen umbenannt werden?

  2. Sicherstellen, dass die geladenen DLLs andere DLLs finden, die sich nicht im Suchpfad befinden.

    (Wenn Sie nicht DLL DLL.dll und DLL2.dll dynamisch geladen haben, dann bin ich nicht sicher, was das wäre. Glücklicherweise sehe ich Sie. :))

    Wenn Sie DLL.dll und DLL2.dll dynamisch laden (also LoadLibrary zur Laufzeit verwenden, anstatt zur Build-Zeit mit ihren .lib-Dateien zu verknüpfen), können Sie SetDllDirectory aufrufen, um die DLL- oder DLL2-Verzeichnisse explizit zur Suche hinzuzufügen Pfad. Sie sollten nur ein Verzeichnis gleichzeitig im Pfad haben, um sicherzustellen, dass die richtige common.dll geladen wurde.

    Beachten Sie, dass es eine gute Übung ist, SetDllDirectory ("") am Anfang Ihres Programms aufzurufen, um das aktuelle Arbeitsverzeichnis ( nicht das Programmverzeichnis, keine Sorge) aus dem Verzeichnis zu entfernen DLL-Suchpfad Dies mildert Sicherheitsprobleme, bei denen Ihr Code zum Laden von DLLs ausgetrickst werden kann. Beachten Sie aber auch, dass Sie den Suchpfad mit SetDllDirectory (NULL) zurücksetzen müssen, um anschließend SetDllDirectory ("") erneut aufzurufen.

Du hättest also einen Code wie diesen:

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole. `
SetDllDirectory("C:\MyExePath\DLL");
LoadLibrary("C:\MyExePath\DLL\DLL.dll");

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole.
SetDllDirectory("C:\MyExePath\DLL2");
LoadLibrary("C:\MyExePath\DLL2\DLL2.dll");

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole.

(Ungetestet so Entschuldigungen für Fehler oder fehlende Argumente. Sollte Ihnen die Idee, aber.)

(Sie sollten den C: \ MyExePath zur Laufzeit berechnen. Harte Codierung wäre natürlich schlecht.)

(Ich gehe davon aus, dass DLL.dll und DLL2.dll ihre common.dll implizit laden. Wenn sie common.dll über einen LoadLibrary-Aufruf laden, ist das Problem noch einfacher: Machen Sie sie einfach ihre eigenen Pfade berechnen und übergeben Sie dann LoadLibrary die volle Pfad zu common.dll.)

Achtung: SetDllDirectory beeinflusst den gesamten Prozess. Wenn Ihr Prozess mehrere Threads aufweist, sollten Sie sicherstellen, dass die SetDllDirectory-Aufrufe voneinander isoliert sind und auch alles andere, das einen LoadLibrary-Aufruf auslösen kann. ZB laden Sie die Bibliotheken beim Start, bevor Sie einen anderen Thread spawnen, wenn möglich.


Ok, das wird wirklich Spaß machen.

Um die DLLs aus anderen Pfaden zu laden, müssen Sie entweder den vollständigen Pfad (bei Verwendung von LoadLibrary) angeben oder die PATH-Umgebungsvariable so erweitern, dass sie die anderen Ordner enthält, die Ihre DLLs enthalten. Einzelheiten hierzu finden Sie unter setenv.

Eine einfache Lösung besteht darin, den relativen Pfad zu LoadLibrary anzugeben. Aber es scheint, dass Sie die DLLs verknüpfen und Sie diese Lösung nicht anwenden können.

Das Problem besteht darin, dass das Laufzeit-Linker das aktuelle Arbeitsverzeichnis und die PATH-Variable verwendet. Da Sie scheinen, die Bibliothek zu verknüpfen, gibt es keine Möglichkeit, Sie können die PATH-Variable direkt nach dem Laden der ersten DLL und vor der zweiten DLL "reparieren". Die verbleibende Lösung besteht darin, die allgemeine DLL in etwas wie common-1.dll und common-2.dll umzubenennen. Dies hat auch den Vorteil, dass Sie sie alle im selben Verzeichnis speichern können.

(Wenn Sie LoadLibrary in jedem Fall verwenden, dann reparieren Sie einfach die PATH var ...)





dll