DLL einbinden
-
Hallo,
ich habe eine eigene DLL mit 2 Funktionen und einer Variablen geschrieben:
DLL_EXPORT int iDllVar=2; //exportierte Variable DLL_EXPORT int DllFuncPlus(int i) { //exportierte Funktion. char buf[256]; int j = i+iDllVar; wsprintf( buf, "i+iDllVar=%d", j ); MessageBox(0,buf,TEXT("Ergebnis"),MB_OK); return j; } DLL_EXPORT int DllFuncMinus(int i) { //exportierte Funktion. char buf[256]; int j = i-iDllVar; wsprintf( buf, "i-iDllVar=%d", j ); MessageBox(0,buf,TEXT("Ergebnis"),MB_OK); return j; }Die passende Header-Datei liegt natürlich auch vor.
Wenn ich die DLL implizit einbinde, also über eine Projektabhängigkeit zwischen DLL und Applikation und einer .lib-Bibliotheksdatei, funktioniert auch alles ohne Probleme. Jetzt möchte ich aber auch eine explizite Einbindung testen.
Auszug aus der Window-Prozedur der Applikation:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { static HWND hwndButtonPlus; static HWND hwndButtonMinus; typedef int ( * DLLFUNC) (int); HINSTANCE hLib; switch (uiMessage) { case WM_CREATE: hwndButtonPlus=CreateWindow (TEXT("button"), TEXT("Addieren"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 30, hWnd, (HMENU)ID_BTN_PLUS, ((LPCREATESTRUCT) lParam)->hInstance , NULL); hwndButtonMinus=CreateWindow (TEXT("button"), TEXT("Subtrahieren"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 50, 150, 30, hWnd, (HMENU)ID_BTN_MINUS, ((LPCREATESTRUCT) lParam)->hInstance , NULL); return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_BTN_PLUS: if (HIWORD(wParam)==BN_CLICKED) { DLLFUNC DllFuncPlus; hLib = GetModuleHandle("DLLTest.dll"); if ( hLib == NULL ) hLib = LoadLibrary("DLLTest.dll"); // Load the DLL now DllFuncPlus = (DLLFUNC) GetProcAddress( hLib, TEXT("DllFuncPlus")); if ( DllFuncPlus != NULL) int i= ((DllFuncPlus)(2)); FreeLibrary(hLib); // Unload DLL from memory } return 0; case ID_BTN_MINUS: if (HIWORD(wParam)==BN_CLICKED) { DLLFUNC DllFuncMinus; hLib = GetModuleHandle("DLLTest.dll"); if ( hLib == NULL ) hLib = LoadLibrary("DLLTest.dll"); // Load the DLL now DllFuncMinus = (DLLFUNC) GetProcAddress( hLib, MAKEINTRESOURCE(2)); if ( DllFuncMinus != NULL) int i= ((DllFuncMinus)(2)); FreeLibrary(hLib); // Unload DLL from memory } return 0; } return 0;Das kompiliert er auch erstmal soweit.
Wenn ich aber die .def Datei einbinde, kommt die Meldung
dll.def : error LNK2001: unresolved external symbol DllFuncMinus
dll.def : error LNK2001: unresolved external symbol DllFuncPlusbeim Linken.
Hier der simple Inhalt der .def-Datei:
LIBRARY DLLTest EXPORTS DllFuncPlus @1 DllFuncMinus @2Habe einfach eine TXT-Datei angelegt und der dann eben den Namen dll.def gegeben, dann unter Source Files des Applikationsprojektes im VisualC++ 6 eingefügt.
Wo ist der Fehler?
Gruß
seventh_son
-
Du musst die Funktionen entweder mit extern "C" markieren oder ins .def-File die C++-dekorierten Namen reinschreiben, wie es z.B. bei der MFC gemacht ist.
-
Wo muß ich extern C einfügen? Im Header?
Kannst du mir mal Code-Beispiele für beide Lösungen geben?
Danke!
-
extern "C" int iDllVar; extern "C" int DllFuncPlus(int i) extern "C" int DllFuncMinus(int i)
-
Ich habe jetzt "DLL_EXPORT" rausgenommen und 'extern "C"' reingenommen, der Fehler bleibt aber der gleiche.
-
Hier die dll.h:
#ifndef DLL_H #define DLL_H #include <windows.h> #ifdef __cplusplus //in windows.h enthalten #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif EXTERN_C int DllFuncPlus( int i ); EXTERN_C int DllFuncMinus( int i ); /////////////////// #endif DLL_H ///////////////////und die dll.cpp:
#define _DLL #include "dll.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // DLL wird in den Adressraum des Prozesses eingeblendet. // Bei einem Fehler return FALSE case DLL_THREAD_ATTACH: // Ein Thread wird erstellt. // Hier können notwendige Initialisierungen durchgeführt werden // Serialisieren: // DisableThreadLibraryCalls( hModule ); // hThread = CreateThread( NULL, 0, SomeFunc, NULL, 0, &dwThreadId ); // WaitForSingleObject( hThread, INFINITE ); // CloseHandle ( hThread ); case DLL_THREAD_DETACH: // Ein Thread wird ordnungsgemäss verlassen. // Hier können notwendige Aufräumarbeiten durchgeführt werden case DLL_PROCESS_DETACH: // Die DLL wird aus dem Prozess-Adressraum ausgeblendet // Hier können notwendige Aufräumarbeiten durchgeführt werden // Auctung! // TerminateProzess() führt NICHT immer DLL_PROCESS_DETACH aus! // if ( pHeap != NULL ) HeapFree( GetProcessHeap(), 0, pHeap ); break; } return TRUE; } EXTERN_C int iDllVar=2; //exportierte Variable EXTERN_C int DllFuncPlus(int i) { //exportierte Funktion. char buf[256]; int j = i+iDllVar; wsprintf( buf, "i+iDllVar=%d", j ); MessageBox(0,buf,TEXT("Ergebnis"),MB_OK); return j; } EXTERN_C int DllFuncMinus(int i) { //exportierte Funktion. char buf[256]; int j = i-iDllVar; wsprintf( buf, "i-iDllVar=%d", j ); MessageBox(0,buf,TEXT("Ergebnis"),MB_OK); return j; }
-
Niemand mehr einen Tip? Ich bin hier fast am Verzweifeln

-
Ich vermute eher mal, dass Du vergessen hast Deine DEF-Datei in den Linker-Settings einzutragen! (Project|Properties|Linker|Input|Module Definition File)
-
Nein, die wurde automatisch eingetragen.
Wenn Du Dir die Fehler anschaust, entstehen die ja auch in der def.-File.
-
Ich habe genau Deinen Source und die DEF-Datei in ein neues DLL-Projekt getan und es klappt wunderbar.
-
Wie gehst du genau vor?
Ich habe ja zwei Projekte, einmal das DLL-Projekt, welches die .dll erstellt, und einmal das Applikations-Projekt. für die .exe Datei. Beide gehören zu einem Arbeitsbereich.
Die .def-Datei habe ich in den Source-Files des Applikationsprojektes eingefügt. Muß sie ins DLL-Projekt? Oder gar in beide Projekte?
Gruß
seventh_son
-
Ins DLL-Projekt gehört sie.
-
Danke euch! Das war der Fehler.