3 Stimmen

Interner Mechanismus des dynamischen Ladens von DLLs in C++ aus der Sicht des Betriebssystems?

Ich bin nicht in der Lage, viele Informationen über das dynamische Laden von DLL-Dateien aus C++ zu erhalten. Ich weiß, dass es einige Funktionen wie LoadLibrary und FreeLibrary mit GetProcAddress verwendet. Aber wie funktioniert es eigentlich intern in der OS-Perspektive, wie z.B. wo es tatsächlich nach der DLL-Datei sucht und wo es Speicher lädt? kann mir jemand mit einigen Diagrammen helfen?

2voto

Cat Plus Plus Punkte 119072

Die Reihenfolge der DLL-Suche wird auf der Seite MSDN und es gibt eine Artikel über das Laden von DLLs und zweiteilig Artikel zur Beschreibung des PE-Formats ( Teil zwei hier ) (sie sind etwas alt, aber ich glaube nicht, dass sie veraltet sind). In den Archiven von MSDN Magazine und MSJ finden Sie wahrscheinlich noch mehr.

1voto

sbi Punkte 211669

Es gibt zwei Möglichkeiten, eine DLL zu verwenden. Sie können sie zur Laufzeit dynamisch laden oder zur Link-Zeit statisch mit ihr verknüpfen.

Wenn Sie es dynamisch laden mit LoadLibrary hat das Betriebssystem einen Mechanismus, um festzustellen, wo nach DLLs zu suchen ist . Es versucht dann, sie zu laden. Dann können Sie versuchen, Funktionszeiger auf die Funktionen zu erhalten, die Sie benennen (durch eine Zeichenkette oder einen gewöhnlichen Namen), und diese Funktionen aufrufen.

Wenn Sie statisch linken, fügt der Linker im Grunde einen Verweis auf die DLL und eine Sprungtabelle mit einem Eintrag für jede Funktion der DLL hinzu. Wenn das Betriebssystem Ihre Anwendung lädt, findet es Verweise auf diese DLLs, versucht, diese zu laden, und fügt die Adressen der Funktionen der geladenen DLL in die Sprungtabelle ein. Erst dann gilt Ihre Anwendung als geladen und wird gestartet.

Beachten Sie, dass dies in Wirklichkeit ein wenig komplizierter ist. Zum Beispiel können DLLs ihrerseits auf andere DLLs verweisen. Wenn also der Lader eine DLL lädt, muss er (möglicherweise rekursiv) auch andere DLLs laden, bevor die DLL als geladen gelten kann.

0voto

Peter Cardona Punkte 2021

Für Win32 finden Sie Details zum Lader auf MSDN. Siehe aquí .

In Ihrem C++-Code haben Sie Recht (für Windows), Sie laden mit ::LoadLibrary und lösen Funktionszeiger mit ::GetProcAddress auf. Normalerweise wandeln Sie das Ergebnis von GetProcAddress in den Typ um, von dem Sie wissen, dass es sich um die Einstiegsfunktion handelt, und verwenden es dann in Ihrem Programm.

Wenn Sie zum Beispiel eine Plugin-Architektur wie einen Browser haben, würden Sie entscheiden, welches Ihr Plugin-Verzeichnis ist, die Liste der Dateinamen für dieses Verzeichnis abrufen und ::LoadLibrary für jede DLL aufrufen (das Filtern der Dateinamen wäre Ihnen überlassen). Für jede DLL würden Sie die erforderlichen Einstiegspunkte mit GetProcAddress auflösen, sie in einer Struktur für diese Bibliothek speichern und sie in eine Plugin-Liste aufnehmen. Später würden Sie diese Funktionszeiger aufrufen, um das Plug-in seine Arbeit tun zu lassen.

Wenn Sie einen relativen Pfad angeben (z. B. "foo.dll" statt "c: \foo.dll "), wird der Suchpfad der OS-Bibliothek aktiviert. Einzelheiten bei MSDN.

Außerdem werden DLLs in den Adressraum Ihres Prozesses geladen. Normalerweise ist es egal, wohin sie geladen werden, aber in der Vergangenheit konnten Sie die Ladezeiten verkürzen, indem Sie Ihre DLLs "umbasen". Ich glaube nicht, dass es irgendwelche Garantien dafür gibt, wie der OS-Lader Bibliotheken im Speicher platziert, aber Sie können immer die Basisadresse im Adressraum Ihres Prozesses erhalten.

Der Einstiegspunkt Ihrer DLL (dllmain) kann auch auf verschiedene Nachrichten reagieren - Thread-Attach, Process-Attach - um die Initialisierung auf sinnvolle Weise durchzuführen.

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