Das Laden der Bibliothek erfolgt mit einem Aufruf von
LoadLibrary(); Ergebnis ist im Erfolgsfall vom Typ HINSTANCE
(hinter dem sich wiederum ein void*
verbirgt, welch ein Wunder!).
Freigeben kann man eine DLL mit FreeLibrary().
Mit GetProcAddress() kann man dann (analog zu dlsym() unter Linux) Zeiger auf die Objekte in der DLL holen.
/////////////////////////////////////////////////////////////////////// // // Time-stamp: "(27.05.01 19:29) dynaufrufer.cpp [Klaus Wachtler]" // // kleine Demo zum Laden und Verwenden einer DLL. // Kompilieren und Linken: // cl -GX dynaufrufer.cpp // Zum Starten muß die demodll.dll im gleichen Verzeichnis sein // (oder sonstwie erreichbar -> PATH-Variable). #include <stdio.h> #include <windows.h> #include <winbase.h> // Typ: Zeiger auf Funktion, die int liefert, zwei int erhält: typedef int ( __stdcall *int_intint_pf_t)( int, int ); // Typ: Zeiger auf Funktion, die int liefert, keine Parameter: typedef int ( __stdcall *int_void_pf_t)( void ); int main() { // Handle für geladene DLL: HINSTANCE DLL_Handle = NULL; // Zeiger auf die Funktion in der DLL: int_intint_pf_t summe_pf = NULL; int_void_pf_t immereinsmehr_pf = NULL; // einmalig die Bibliothek laden: DLL_Handle = LoadLibrary( "demodll.dll"); if( !DLL_Handle ) { // Laden dder DLL hat nicht geklapppt! // Mit GetLastError() könnte man jetzt eine Kennung des // aufgetretenen Fehlers beschaffen; was man mit dieser Kennung // dann anstellt habe ich nicht verstanden :-( fprintf( stderr, "Fehler beim Laden der DLL!\n" ); exit( 2 ); } // Zeiger auf die darin enthaltenen Funktionen holen: summe_pf = (int_intint_pf_t)GetProcAddress( DLL_Handle, "summe" ); immereinsmehr_pf = (int_void_pf_t)GetProcAddress( DLL_Handle, "immereinsmehr" ); // Funktion gefunden? if( !summe_pf ) { // Nö! fprintf( stderr, "Fehler! Funktion summe() nicht gefunden\n" ); exit( 2 ); } // Funktion gefunden? if( !immereinsmehr_pf ) { fprintf( stderr, "Fehler! Funktion immereinsmehr() nicht gefunden\n" ); exit( 2 ); } // und beliebig oft benutzen: for( int i=0; i<10; i++ ) { try { printf( "Summe von %d und %d ist %d; immer eins mehr ist %d\n", i, i/2, (*summe_pf)( i, i/2 ), (*immereinsmehr_pf)() ); } catch( int Fehler ) { fprintf( stderr, "int-Ausnahme %d gefangen!\n", Fehler ); } catch( ... ) { fprintf( stderr, "irgendeine Ausnahme gefangen!\n" ); } Sleep( 1000 ); } // Mann kann die DLL auch wieder entladen, wenn man sie nicht // mehr braucht (FreeLibrary()). // Kann man sich aber auch sparen. FreeLibrary( DLL_Handle ); return 0; } // ///////////////////////////////////////////////////////////////////////
Das Beispielprogramm kann folgendermaßen übersetzt und gestartet
werden (die Compileroption -GX
ist nötig, weil Ausnahmen
verwendet werden, was in C++ ja so ungewöhnlich ist!):
C:\temp\dynBib\win32>cl -GX dynaufrufer.cpp Optimierender Microsoft (R) 32-Bit C/C++-Compiler, Version 12.00.8168, fuer x86 Copyright (C) Microsoft Corp 1984-1998. Alle Rechte vorbehalten. dynaufrufer.cpp Microsoft (R) Incremental Linker Version 6.00.8168 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. /out:dynaufrufer.exe dynaufrufer.obj C:\temp\dynBib\win32>dynaufrufer DllMain: DLL_PROCESS_ATTACH Summe von 0 und 0 ist 0; immer eins mehr ist 0 Summe von 1 und 0 ist 1; immer eins mehr ist 1 Summe von 2 und 1 ist 3; immer eins mehr ist 2 Summe von 3 und 1 ist 4; immer eins mehr ist 3 Summe von 4 und 2 ist 6; immer eins mehr ist 4 Summe von 5 und 2 ist 7; immer eins mehr ist 5 Summe von 6 und 3 ist 9; immer eins mehr ist 6 int-Ausnahme 125 gefangen! int-Ausnahme 125 gefangen! int-Ausnahme 125 gefangen! DllMain: DLL_PROCESS_DETACH
Ein analoges Kommando zu ltrace gibt es meines Wissens unter Windows nicht.