erstellte DLL mit Code::Blocks(8.02) geht nicht



  • Hi,
    ich habe eine DLL mit Code::Blocks Version 8.02 erstellt.

    #include <windows.h>
    
    // a sample exported function
    void SomeFunction(const LPCSTR sometext)
    {
        MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                SomeFunction("test");
                // attach to process
                // return FALSE to fail DLL load
                break;
    
            case DLL_PROCESS_DETACH:
                // detach from process
                break;
    
            case DLL_THREAD_ATTACH:
                // attach to thread
                break;
    
            case DLL_THREAD_DETACH:
                // detach from thread
                break;
        }
        return FALSE;
    }
    

    Nur mal zum Testen.

    Jetzt lade ich Sie in einem anderem Programm:

    int main()
    {
        printf("%u", (unsigned) LoadLibrary("D:\\test.dll"));
    
        return 0;
    }
    

    Als return Wert kommt nicht 0 obwohl ich ja in der DLL Main FALSE returne & die MessageBox erscheint auch nicht.

    Was ist mein Fehler?

    Mit einer älteren Version von C::B hats noch funktioniert. Und die hat au nicht eine .cpp Datei erstellt was mich iwie au wundert.

    Danke für jede Hilfe 🙂

    Gruß Pingu



  • Hallo.

    1. Steht die DLL neben der EXE (oder ab ins system32 und danach regsvr32.exe)?
    2. Wenn DllMain false zurückgibt, geht eine Messagebox auf. (siehe 1.)
    3. Schon mal Breakpoints im Debugger gesetzt?
    4. Guter Stil bei DLLs:
    - Header
    - cpp
    - SomeName.lib (muss du anmachen in Settings)
    5. Schlechter Stil bei DLLs:
    - In DllMain Funktionen aufrufen, die nicht aus dem Kernel kommen.

    Guter Stil (der auch gleichzeitig zeigt, welche Macht DLLs haben können):

    //-------------------------------------------------------------------
    //shared data
    
    #pragma data_seg(".gShared")
    
    	unsigned char	gs_globalData[SIZE_MEMORY] = {0};
    	unsigned char	gs_adrMap[NUM_CHANNELS] = {0};
    	LONG			gs_countConnects = 0;
    
    #pragma data_seg()
    
    #pragma comment(linker, "/SECTION:.gShared,RWS")
    
    //-------------------------------------------------------------------
    
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
    	int		ok, i;
    
        switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    			if (gs_countConnects == NUM_CHANNELS)
    			{
    				MessageBox(NULL,"Too many processes.\nAccess denied.","DLL",MB_OK);			
    				return false;
    			}
    
    			for (i=0;i<NUM_CHANNELS;i++)
    			{
    				g_hMutex[i] = CreateMutex(NULL,false,g_MutexName[i]);
    				if (g_hMutex[i] == NULL) 
    				{
    					MessageBox(NULL,"Creating mutex failed.\nAccess denied.","DLL",MB_OK);
    					return false;
    				}
    			}
    
    			g_hProcess = GetCurrentProcess();
    			if (!DuplicateHandle(g_hProcess,g_hProcess,g_hProcess,&g_hProcess, 
    								 0,false,DUPLICATE_SAME_ACCESS))
    			{
    					MessageBox(NULL,"Initialization failed.\nAccess denied.","DLL",MB_OK);
    					return false;
    			}
    
    			InterlockedIncrement(&gs_countConnects);
    			break;
    
    		case DLL_THREAD_ATTACH:
    			break;
    
    		case DLL_THREAD_DETACH:
    			break;
    
    		case DLL_PROCESS_DETACH:
    
    			for (i=0;i<NUM_CHANNELS;i++)
    			{
    				ok = CloseHandle(g_hMutex[i]);
    				g_hMutex[i] = NULL;
    				if(ok == 0)
    				{
    					MessageBox(NULL,"Closing control failed","DLL",MB_OK);
    					return false;
    				}
    			}
    
    			InterlockedDecrement(&gs_countConnects);
    			break;
        }
        return true;
    }
    


  • ... ist das



  • Das, was DllMain zurückgibt (true/false) ist der Rückgabewert von LoadLibrary.



  • DllMain retVal schrieb:

    Das, was DllMain zurückgibt (true/false) ist der Rückgabewert von LoadLibrary.

    Stimmt aber so nicht ganz:

    MSDN schrieb:

    If the specified module is a DLL that is not already loaded for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If DllMain returns TRUE, LoadLibrary returns a handle to the module. If DllMain returns FALSE, the system unloads the DLL from the process address space and LoadLibrary returns NULL.

    chezzmatazz schrieb:

    Hallo.

    1. Steht die DLL neben der EXE (oder ab ins system32 und danach regsvr32.exe)?
    2. Wenn DllMain false zurückgibt, geht eine Messagebox auf. (siehe 1.)
    ....
    5. Schlechter Stil bei DLLs:
    - In DllMain Funktionen aufrufen, die nicht aus dem Kernel kommen.

    zu 1.
    DLL liegt halt auf "D:"

    zu 2. nö kommt einfach garnichts und LoadLibrary gibt au nicht NULL zurück

    zu 5.

    Habs mal so probiert:

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                MessageBox(0, "test", "test", MB_OK);
                // attach to process
                // return FALSE to fail DLL load
                break;
    
            case DLL_PROCESS_DETACH:
                // detach from process
                break;
    
            case DLL_THREAD_ATTACH:
                // attach to thread
                break;
    
            case DLL_THREAD_DETACH:
                // detach from thread
                break;
        }
        return FALSE;
    }
    

    Geht aber genauso wenig 😞
    Keine MessageBox kommt und ein Handle wird auch returnt.

    Gruß Pingu



  • chezzmatazz halt die klappe und laber keinen müll, wenn du 0 ahnung hast.

    @topic: der code ist in ordnung.



  • @ascada: Bist du immer noch Student? Sieh mal zu, dass du fertig wirst!

    Aber das Bückstück hat Recht: Der Code ist i.O.

    Die EXE muss im selben Verzeichnis stehem wie die DLL (z.B. Debug).
    Hast Du die DLL in das Verzeichnis kopiert, in dem die EXE steht (z.B. Debug)? Oder im OS registriert? "DLL liegt halt auf D" funktioniert nur, wenn "EXE halt auch nur auf D liegt".
    Du arbeitest mit LoadLibrary, und die Funktion gibt true zurück. Die Pfade stimmen also. Aber dieser Satz bedarf noch einer Erklärung:

    Keine MessageBox kommt und ein Handle wird auch returnt.

    Das ist ein Widerspruch.

    Kannst Du (funktionierende!) Breakpoints in der DLL setzen? Also ohne Meldungen wie "Breakpoint kann nicht erreicht werden"?.



  • Also ich hab jetzt das Problem damit umgangen, indem ich einfach eine andere IDE verwende: Visual Studio 2008 Express

    @chezzmatazz danke für deine Hilfe, aber ich hab jetzt au gar keine lust mehr mich damit rumzuärgen wenns mit VC++ geh :). Muss jettz noch ein bissle schlafen;)

    Grüßli & gute Nacht Pingu


Anmelden zum Antworten