Verständnissfrage WinAPI - kernel32.dll etc.
-
Ein Standard Windows Projekt linkt folgende Objekt Files statisch mit ein:
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.libDie einfache .exe hat eine Grösse von 7KB. Viele der Funktionen aus kernel32.dll und user32.dll sind im windows.h-Header definiert.
Werden nun, nur die Instruktionsblöcke aus den LIB's in die fertige exe gelinkt auf welchem ich irgendwo verweise? Das würde aber ja bedeuten das die kernel32 Funktionen mehrfach im Arbeitsspeicher (für jeden Prozess) existieren.
Von wo weiss jetzt der Linker wo sich die "GetCurrentDirectory" in den Libs befindet? Heisst das, dass nur Funktionen die im Export Table aufgelistet sind (_dspecl(dllexport)) dem Linker (beim statischem compilen) und über GetProcAddress (beim dynamischen linken) vorhanden sind.
Sind meine Aussagen korrekt?
-
Der Compiler macht ja nichts anderes als intern über eine Art GetProcAdress() die Addresse über den Funktionsnamen zu holen - vorausgesetzt die Funktion ist im Export-Table vorhanden - sonst hätte der Compiler ja keine Ahnung wo er "GetCurrentDirectory" suchen müsste. Nimmt den Block, klebt es in meine Exe.
Nun beim dynamischen Linken kann ich die Ziel-DLL ja angeben, und von wo weiss der Linker beim statischem Linken ob ich jetzt die Export-Funktion aus A.dll oder die aus der B.dll meine?
-
Wenn Du eine a.dll und eine b.dll mit einer identischen Funktion void funk() hast, dann haut Dir der Linker auf die Finger, wenn Du versuchst, a.lib und b.lib zu Deiner exe zu linken.
Im anderen Fall wird beim Starten Deiner exe nachgesehen, welche von den benötigten DLLs noch nicht geladen sind, diese werden dann nachgeladen und los gehts.
-
Habs grad ausprobiert. Bei mir nimmts entweder die Lokale Funktion oder er durchstöbert die LIB's und nimmt die er erst findet. Keine Fehlermeldung.
Belli schrieb:
Im anderen Fall wird beim Starten Deiner exe nachgesehen, welche von den benötigten DLLs noch nicht geladen sind, diese werden dann nachgeladen und los gehts.
Das verstehe ich überhaupt nicht. Das sind ja statisch gelinkte Libraries diese ganzen system libs. Ich sehe nichts von einer dynamischen Linkung.
-
Mhm, sieht tatsächlich so aus, als ob der Linker einfach die Funktion einbindet, die er zuerst findet ...
Das statische Binden einer DLL, also das einbeziehen in den Linkvorgang durch Angabe der lib - Datei, führt dazu, dass die DLL beim Start der exe geladen wird, wenn sie das nicht sowieso schon ist.
Dynamisches Binder der DLL heisst, im Programm die DLL bei Bedarf via LoadLibrary zu laden, die exe - Datei startet auch erst mal, ohne dass die DLL überhaupt vorhanden sein muss, und scheitert erst bei LoadLibrary.
Beim statischen Binden würde die exe gar nicht starten, wenn die DLL nicht gefunden wird.
-
Schau dir mal an was der Unterschied zwischen Load-Time Dynamic Linkig und Run-Time Dynamic Linking ist und was eine Import Lib ist.
Prinzipiell linkst du da eine spezielle Art von .lib die nur dafür sorgt dass der Linker in der erzeugten exe Verweise auf die entsprechenden dlls anbringt. Das Betriebssystem schaut beim Laden der exe in dieser Tabelle nach und lädt die benötigten dlls und Funktionen daraus.
-
Hab mal nachgelesen wie das funktioniert. Das quasi ein Platzhalterfunktion erstellt wird, dieser JUMP schlussentlich auf die ermittelte Adresse der DLL's.
Nun jetzt verstehe ich nur noch nicht, wieso man dann überhaupt LIB inkludieren muss. Und wie erstelle ich selber so einen Load-Time Lib mit Dll?
-
jemen schrieb:
Nun jetzt verstehe ich nur noch nicht, wieso man dann überhaupt LIB inkludieren muss. Und wie erstelle ich selber so einen Load-Time Lib mit Dll?
Eine Import Lib ist nur eine Möglichkeit wie Load Time Dynamic Linking von vielen Compilern implementiert wird. Am Ende gehts nur drum was in der exe drinsteht. Wenn du mit Visual Studio eine dll erstellst dann generiert der Compiler auch automatisch eine Import Lib dazu, sofern du das nicht explizit abgestellt hast.