// Literatur: Vorlesungsunterlagen ISE3 (FH-Hagenberg) /*********************************************************************/ /* Projekt für dynamische Library (erzeugt dll.dll) */ /* bei DevCpp wird libDLL.a und libDLL.def erzeugt, */ /* bei VS sollte eine dll.def selbst angelegt werden */ /* und dll.lib wird erzeugt */ /*********************************************************************/ // dll.h: //--------------------------------------------------------------------- #ifndef _DLL_H_ #define _DLL_H_ #if BUILDING_DLL # define DLLIMPORT __declspec (dllexport) #else # define DLLIMPORT __declspec (dllimport) #endif extern DLLIMPORT int var; DLLIMPORT int func(void); // name mangling DLLIMPORT int Add1(int const val1, int const val2); // without name mangling extern "C" DLLIMPORT int Add2(int const val1, int const val2); class DLLIMPORT dllClass { public: dllClass(); virtual ~dllClass(void); }; #endif // dll.cpp: //--------------------------------------------------------------------- #include "dll.h" #include <windows.h> BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBox(0, "DLL_PROCESS_ATTACH called", "DLL", MB_OK); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: MessageBox(0, "DLL_PROCESS_DETACH called", "DLL", MB_OK); break; } return TRUE; } DLLIMPORT int var=0; DLLIMPORT int func(void) { return 42; } DLLIMPORT int Add1(int const val1, int const val2) { return val1 + val2; } extern "C" DLLIMPORT int Add2(int const val1, int const val2) { return val1 + val2; } dllClass::dllClass() { MessageBox(0, "dllClass CTOR called", "DLL", MB_OK); return; } dllClass::~dllClass() { MessageBox(0, "dllClass DTOR called", "DLL", MB_OK); return; } // dll.def (bei DevCpp nicht nötig): //--------------------------------------------------------------------- LIBRARY "DLL" DESCRIPTION 'My personal dll :-)' EXPORTS var func Add1 Add2 /*********************************************************************/ /* Projekt welches die Library verwendet */ /* dll.h und libDLL.a/dll.lib werden ins aktuelle Projekt kopiert, */ /* libDLL.a/dll.lib wird bei den Abhängigkeiten des Linkers */ /* eingetragen */ /*********************************************************************/ // testDll.h: //--------------------------------------------------------------------- #include <iostream> #include <conio.h> #include "dll.h" using namespace std; int main() { cout << "var = " << var << endl; var = 3; cout << "var = " << var << endl; cout << "func() = " << func() << endl; cout << "Add1(1,2) = " << Add1(1,2) << endl; cout << "Add2(1,2) = " << Add2(1,2) << endl; dllClass *cl = new dllClass(); delete cl; _getch(); return 0; } /*********************************************************************/ /* Projekt welches die Library zur Laufzeit lädt */ /*********************************************************************/ // testDll2.h: //--------------------------------------------------------------------- #include <iostream> #include <windows.h> #include <conio.h> using namespace std; int main () { // Funktionspointer gemaess der Schnittstelle typedef int (* TAdd) (int const, int const); // DLL dynamisch zur Laufzeit laden HMODULE hDll = LoadLibrary("dll.dll"); if (hDll != 0) { // Funktionsadresse ermitteln // via Namen TAdd pAdd1 = (TAdd) GetProcAddress(hDll, "Add1"); // via Ordinalnummer //TAdd pAdd1 = (TAdd) GetProcAddress(hDll, MAKEINTRESOURCE(3)); if (pAdd1 != 0) cout << "Add1(1,2) = " << pAdd1(1,2) << endl; else cout << "Add1 not found (maybe name mangling)" << endl; TAdd pAdd2 = (TAdd) GetProcAddress(hDll, "Add2"); if (pAdd2 != 0) cout << "Add2(1,2) = " << pAdd2(1,2) << endl; else cout << "Add2 not found (maybe name mangling)" << endl; } // Clean up FreeLibrary(hDll); _getch(); return 0; }