DLL-Funktionen nicht gefunden



  • Hi, ich hab ne DLL geschrieben, die 2 Funktionen hat:

    EXPORT BOOL CALLBACK OnInitialize(HWND);
    EXPORT BOOL CALLBACK OnShutdown(void);

    Im Programm versuch ich darauf zuzugreifen, aber meine Messageboxen sagen immer wieder, dass die Funktionen nicht gefunden werden können. Warum? Ich habe mein altes Projekt nur überarbeitet (neue VS C++ Version) und schon gehts nich mehr oder was?

    Header der DLL

    #ifdef __cplusplus
    #define EXPORT extern "C" __declspec (dllexport)
    #else
    #define EXPORT __declspec (dllexport)
    #endif
    
    EXPORT BOOL CALLBACK OnInitialize(HWND);
    EXPORT BOOL CALLBACK OnShutdown(void);
    

    Source der DLL

    HINSTANCE   hDllInstance;
    
    int APIENTRY DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
    {
        switch (fdwReason)
    	{
            case DLL_PROCESS_ATTACH :
                hDllInstance = hInstance ;
                break ;
        }  
        return TRUE ;
    }
    
    EXPORT BOOL CALLBACK OnInitialize(HWND hwnd)
    {
    //Funktionssource...
    }
    
    EXPORT BOOL CALLBACK OnShutdown()
    {
    //Funktionssource...
    }
    

    Hier der Source des Testprojekts für die DLL:

    #include <windows.h>
    #include <commctrl.h>
    #include <commdlg.h>
    
    #define WINDOW_WIDTH	640
    #define WINDOW_HEIGHT	480
    
    #pragma warning(disable : 4996 )
    #pragma comment(lib, "comctl32.lib")
    
    typedef bool(*ONINITIALIZE)(HWND hParent);
    typedef bool (*ONSHUTDOWN)();
    
    ONINITIALIZE Initialize = NULL;
    ONSHUTDOWN Shutdown = NULL;
    
    HMODULE hLibrary;
    
    LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
    
    TCHAR CurrentKey;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
    {
    	HWND hwnd;
    	MSG msg;
    	WNDCLASSEX wcx;
    
    	InitCommonControls();
    
    	wcx.hInstance = hInstance;
    	wcx.lpszClassName = L"KeyTestClass";
    	wcx.lpfnWndProc = WindowProcedure;
    	wcx.style = CS_DBLCLKS;
    	wcx.cbSize = sizeof(WNDCLASSEX);
    	wcx.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    	wcx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
    	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wcx.lpszMenuName = NULL;
    	wcx.cbClsExtra = 0;
    	wcx.cbWndExtra = 0;
    	wcx.hbrBackground = (HBRUSH) COLOR_BTNSHADOW;
    
    	RegisterClassEx(&wcx);
    
    	//Hauptfenster
    	hwnd = CreateWindowEx(0, 
    						  L"KeyTestClass", 
    						  L"Key", 
    						  WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX,
    						  (GetSystemMetrics(SM_CXSCREEN)-WINDOW_WIDTH)/2, 
    						  (GetSystemMetrics(SM_CYSCREEN)-WINDOW_HEIGHT)/2, 
    						  WINDOW_WIDTH, 
    						  WINDOW_HEIGHT, 
    						  HWND_DESKTOP, 
    						  NULL, 
    						  hInstance, 
    						  NULL
    						 );
    
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg); 
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC hdc;
    	PAINTSTRUCT ps;
    
    	switch(message)
    	{
    		case WM_CREATE:
    			hLibrary = LoadLibrary(L"Key.dll");
    
    			if (hLibrary == NULL)
    				MessageBox(hwnd, L"No DLL", L"", NULL);
    
    			Initialize = (ONINITIALIZE)GetProcAddress(hLibrary, "OnInitialize");
    			Shutdown = (ONSHUTDOWN)GetProcAddress(hLibrary, "OnShutdown");
    
    			if (Initialize == NULL)
    				MessageBox(hwnd, L"No Func OnInitialize", L"", NULL);
    			if (Shutdown == NULL)
    				MessageBox(hwnd, L"No Func OnShutdown", L"", NULL);
    			break;
    
    		case (WM_USER+2):
    			CurrentKey = wParam;
    			InvalidateRect(hwnd, NULL, true);
    			break;
    
    		case WM_PAINT:
    			hdc = BeginPaint(hwnd, &ps);
    				TextOut(hdc, 10, 10, &CurrentKey, wcslen(&CurrentKey));
    			EndPaint(hwnd, &ps);
    			break;
    
    		case WM_CLOSE:
    			FreeLibrary(hLibrary); 
                DestroyWindow(hwnd);
    			break;
    
    		case WM_DESTROY:
    			PostQuitMessage(0); 
    			break;
    
    		default: 
    			return DefWindowProc(hwnd, message, wParam, lParam);
    	}
    	return 0;
    }
    

    Wo liegt hier das Problem? Ich hoffe hier kann mir jemand helfen. (Die DLL kann gefunden werden, nur die Funktionen nich).

    €dit: Funktionen berichtigt.



  • Schau mal mit
    www.dependecywalker.com
    nach wie die Funktionen in der DLL *wirklich* heissen!

    Verwende dann eine DEF-Datei, damit sie den Namen bekommen, wie Du willst...



  • Naja wirklich heißen tun sie:

    _OnInitialize und _OnShutdown

    und die laufen auch nicht.



  • Die erste MessageBox wird angezeigt wenn "HookSetup" == NULL ist. Prüf lieber mal ob "Initialize" == NULL ist.



  • roflé...



  • Nolf schrieb:

    Naja wirklich heißen tun sie:
    _OnInitialize und _OnShutdown
    und die laufen auch nicht.

    naja, ich würde eher sagen die heissen:
    _OnInitialize@4 und _OnShutdown@0



  • Joa ich weis aber das hab ich ja nich mitgeschrieben ich kann das ja nicht so in den Quellcode übernehmen oder?
    Zu dem Hooksetup: Das ist einfach nur ein schreibfehler weils die Variable nicht gibt, ich hab den Quellcode im Forum hier ein bissn umgeändert also daran liegts nicht.

    Edit: Es funktioniert. Ich hab die doch mit dem @x geschrieben aber warum ist das so? Ich hab die Funktionen doch nicht so benannt oder sind das Positionsangaben im Code?

    Ein Problem kommt aber noch: Wenn ich die OnShutdown funktion EGAL wo verwende, stürzt mein Programm einfach ab.
    Der Debugger sagt:

    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    Das verstehe ich nicht wirklich. Was bedeutet das?



  • Nolf schrieb:

    Joa ich weis aber das hab ich ja nich mitgeschrieben ich kann das ja nicht so in den Quellcode übernehmen oder?

    Du sollst ja auch eine DEF-Datei verwenden, damit die Namen so sind wie Du sie erwartest... (sag ich schon zum 2. Mal).

    Nolf schrieb:

    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    In der DLL wird die Funktion als __stdcall definiert und Du verwendest sie als __cdecl.



  • OK ich habs mit den Funktionen verändert (in den Projekteinstellungen auf __stdcall gesetzt [geht das auch im Quellcode?]). Sorry ich kenn mich mit den DEF dateien nicht aus und deswegen habe ich darauf nicht geachtet. Diese @x stören auch nicht so.

    Danke
    mfg Nolf



  • stells nicht in den projekteinstellungen um, nur die funktionen, die du aus der dll importierst musste __stdcall benutzen.


Anmelden zum Antworten