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