Wann ein Handle von einer DLL mit LoadLibrary() und wann mit GetModuleHandle() ermitteln?
-
Hi Folks,
in meiner App benötige ich dynamische Funktionen, die ich mittels GetProcAddress() bekomme.
Und zwar ganz speziell diese aus Windows-eigenen DLLs wie z.B. kernel32.dll, comctl32.dll usw..
Nur so sichere ich eine Abwärtskompatibilität der App auf älteren Systemen wie z.B. Win2000.Methode (1) mit GetModuleHandle():
pfn_IWOW64P = (FN_IWOW64P)GetProcAddress( GetModuleHandle( TEXT("kernel32.dll") ), "IsWow64Process" );
Methode (2) mit LoadLibrary():
pfn_IWOW64P = (FN_IWOW64P)GetProcAddress( LoadLibrary( TEXT("kernel32.dll") ), "IsWow64Process" );
(Wie immer Beispiele ohne die obligatorischen Fehlerabfragen, damit die Lesbarkeit nicht darunter leidet)
Woher weiß ich, wann ich eine DLL mit LoadLibrary() laden muß oder wann genügt es nur GetModuleHandle() zu verwenden?
Ich meine, es ist schon einleuchtend, daß eine DLL einmal geladen sein muß, bevor GetModuleHandle() verwendet werden kann.Bei kernel32.dll mag es trivial sein, daß diese DLL beim Programmstart immer geladen ist.
Doch wer garantiert das?
Und wie sieht es mit den anderen (nicht ganz so trivialen) DLLs aus, wie z.B. shlwapi.dll und uxtheme.dll ?Könnt Ihr mir da ein bißchen Aufklärung leisten?
Martin
-
MSDN:
GetModuleHandle Function
Retrieves a module handle for the specified module. The module must have been loaded by the calling process.LoadLibrary benutzen, um eine DLL für dein Programm zu nutzen.
Windows pflegt einen "Instanzenzähler" für aktuell geladene DLLs und entscheidet bei einem Aufruf von LoadLibrary() selbst, ob tatsächlich geladen werden muß, oder eine bereits im Speicher befindliche genutzt werden kann und nur der "Instanzenzähler" erhöht wird./Ulli
-
Danke für Deinen Hinweis,
mir ist es schon bewußt, daß die DLL geladen sein muß, bevor man GetModuleHandle() anwendet.
Das habe ich auch schon geschrieben.Die Frage ist nur, welche DLLs sind beim Programmstart "automatisch" durch Windows geladen.
D.h. solche DLLs könnte ich dann direkt mit GetModuleHandle() ermitteln.
Und zwar ohne LoadLibrary() und FreeLibrary() handhaben zu müssen.Alleine der Aufruf von GetModuleHandle() erzwingt eigentlich schon das Laden des Moduls kernel32.dll.
Und dieses bleibt bis zum Ende des Prozesses geladen.
Stimmt das so? Oder irre ich mich dabei?Martin
-
Benutz am besten immer LoadLibrary für so etwas. GetModuleHandle returnt 0 wenn die dll nicht geladen ist. Dann musst du sowieso LoadLibrary aufrufen.
-
keiner garantiert das.
Du kannst GetModuleHandle nur verwenden wenn du sicher bist, dass die DLL geladen ist.Wenn du es nicht bist entweder nachgucken und gegebenenfalls laden oder
LoadLibrary verwenden. Wenn sie dann bereits geladen ist auch kein Problem, dann wird nur der Counter erhöht.
-
Alles klar, Danke für Eure Infos.
Habe ein kleines Modul (bzw. Klasse) erstellt, welches sich um korrekte Handhabung von DLLs kümmert.
Bei jeder erstmaligen Verwendung einer DLL wird LoadLibrary() angewendet.
Bei jeder weiteren Verwendung der gleichen DLL wird nur noch das zwischengespeicherte Handle der jeweiligen DLL sofort zurückliefert.Und natürlich FreeLibrary() für jedes bereits geladene DLL bei Programmende...
Danke
MartinP.S.: Es ist schon erstaunlich, wieviele Sourcen und Beispiele (auch auf MSDN!!!) nur GetModuleHandle() verwenden, ohne sich vorher jemals um LoadLibrary() bemüht zu haben...
-
Wo ist Dein Problem. Wenn implizit klar ist, dass eine DLL benutzt wird, dann kann man sich auf GetModuleHandle verlassen.
Was implizit geladen wird ist schnell mit Depends heraus gefunden...uxtheme ist sowieso auch nur dann geladen, wenn Theming eingestellt ist und nicht Windows Classic verwendet wird.
Warum solltest Du hier LoadLibrary benutzen, wenn es sowieso nicht klar ist ob die DLL überhaupot benutzt wird und benutzt werden kann!Man kann GetModuleHandle immer verwenden. Man muss nur damit rechnen, dass eben NULL zurück kommt!
Ein weiteres Problem in der Gallerie sind delay loaded Modules...
-
Martin Richter schrieb:
Was implizit geladen wird ist schnell mit Depends heraus gefunden...
Das heißt also:
In den Linker-Einstellungen kann man Objekt-/Bibliothek-Module eingeben, dort steht z.B. shlwapi.lib.
Depends zeigt mir die DLL-Module an, die meine Applikation verwendet, z.B. shlwapi.dll.
Diese DLLs werden also bei Programmstart automatisch geladen?Martin Richter schrieb:
uxtheme ist sowieso auch nur dann geladen, wenn Theming eingestellt ist und nicht Windows Classic verwendet wird.
Warum solltest Du hier LoadLibrary benutzen, wenn es sowieso nicht klar ist ob die DLL überhaupot benutzt wird und benutzt werden kann!Ich benutze LoadLibrary() nur dann, wenn ich Funktionen benutze, die in älteren Windows-Versionen nicht verfügbar sind, wie eben solche in uxtheme.dll.
Ältere industrielle Maschinen mit z.B. Win2000 oder WinCE können wir supportmäßig prinzipbedingt nicht fallenlassen.Martin
-
Mmacher schrieb:
Martin Richter schrieb:
Was implizit geladen wird ist schnell mit Depends heraus gefunden...
Das heißt also:
In den Linker-Einstellungen kann man Objekt-/Bibliothek-Module eingeben, dort steht z.B. shlwapi.lib.
Depends zeigt mir die DLL-Module an, die meine Applikation verwendet, z.B. shlwapi.dll.
Diese DLLs werden also bei Programmstart automatisch geladen?Ja.
-
Danke für die Info.
Martin