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 DllFuncPlus

    beim Linken.

    Hier der simple Inhalt der .def-Datei:

    LIBRARY DLLTest
    
    EXPORTS
    	DllFuncPlus @1
    	DllFuncMinus @2
    

    Habe 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.


Anmelden zum Antworten