02. juli 2004 - 10:35
Der er
29 kommentarer og 1 løsning
Load Dll dynamisk, og bruge den funktioner.
Måske giver jeg for let op, men jeg er ved at blive tosset over hvordan jeg skal bruge DLL'er effektivt... Min kode til DLL'en er sådan her: #include <windows.h> HHOOK g_hMouseHook = NULL; HWND hWndApp = NULL; HINSTANCE hInstDLL = NULL; bool WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(lpvReserved); switch(fdwReason) { case DLL_PROCESS_ATTACH: MessageBox(NULL,"PAttach","SET",MB_OK); hInstDLL = hInstance; break; case DLL_THREAD_ATTACH: MessageBox(NULL,"TAttach","SET",MB_OK); break; case DLL_THREAD_DETACH: MessageBox(NULL,"TDetach","SET",MB_OK); break; case DLL_PROCESS_DETACH: MessageBox(NULL,"PDetach","SET",MB_OK); break; } return true; } bool __declspec(dllexport)printfDll(LPTSTR lpTxt) { MessageBox(NULL,lpTxt,"INFO",MB_OK); return true; } Og til selve programmet: #include <stdio.h> #include <windows.h> typedef VOID (*MYPROC)(LPTSTR); void error(LPSTR); VOID main(VOID) { MYPROC ProcAdd; HINSTANCE hinstLib; bool fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module. hinstLib = LoadLibrary("mydll.dll"); // If the handle is valid, try to get the function address. if (hinstLib != NULL) { printf("+ LoadLibrary Done\n"); ProcAdd = (MYPROC) GetProcAddress(hinstLib, "printDll"); // If the function address is valid, call the function. if (NULL != ProcAdd) { printf("+ GetProcAddress Done\n"); fRunTimeLinkSuccess = TRUE; (ProcAdd) ("message via DLL function\n"); } else { printf("- GetProcAddress Failed\n"); error("GetProcAddress"); } // Free the DLL module. FreeLibrary(hinstLib); } else { printf("- LoadLibrary Failed\n"); error("LoadLibrary"); } // If unable to call the DLL function, use an alternative. if (! fRunTimeLinkSuccess) printf("message via alternative method\n"); } void error(LPSTR lpszFunction) { CHAR szBuf[80]; DWORD dw = GetLastError(); sprintf(szBuf, "%s failed: GetLastError returned %u\n", lpszFunction, dw); MessageBox(NULL, szBuf, "Error", MB_OK); ExitProcess(dw); } Jeg får fejlen: Hvor den skal GetProcAddress, og windows error code: 127 The specified procedure could not be found. Men den skulle da gerne være der, eller tager jeg fejl? Noge som kan hjælpe?
Annonceindlæg fra COMM2IG
bool __declspec(dllexport)printfDll(LPTSTR lpTxt) ProcAdd = (MYPROC) GetProcAddress(hinstLib, "printDll"); med eller uden f ?
Har ændret: ProcAdd = (MYPROC) GetProcAddress(hinstLib, "printDll"); til: ProcAdd = (MYPROC) GetProcAddress(hinstLib, "printfDll"); Men får samme fejl!
Der er også lidt blandede udmeldinger om returværdi bool eller void. Men det tror jeg nu ikke har nogen effekt.
Oversætter du som C eller C++ ? Hvis C++ kan du prøve: extern "C" { } omkring funktionen.
Jeg bruger BCC32, og mine filer ender på CPP, så det må være C++! Jeg har nu sat dette på: extern "C" { bool __declspec(dllexport)printfDll(LPTSTR lpTxt) { MessageBox(NULL,lpTxt,"INFO",MB_OK); return true; } } Stadig ingenting... Samme fejl...
Måske du kan hjælpe! Det jeg ønsker er følgende: En dll-fil, som indeholder 2 funktioner: f.eks.: int getValue(); void setValue(int i);
Nu er jeg kommet lidt længere: test2dll.cpp #include <windows.h> static int i = 0; extern "C" int __declspec(dllexport) WINAPI GetInt() { MessageBox (NULL, "GET", "INFORMATION", NULL ); return i; } extern "C" bool __declspec(dllexport) WINAPI SetInt(int t) { MessageBox (NULL, "SET", "INFORMATION", NULL ); i = t; return true; } test2exe.cpp #include <stdio.h> #include <windows.h> typedef int (*MYPROC1)(void); typedef bool (*MYPROC2)(int); void error(LPSTR); bool main(void) { MYPROC1 ProcAdd1; MYPROC2 ProcAdd2; HINSTANCE hinstLib; bool fRunTimeLinkSuccess = false; // Get a handle to the DLL module. hinstLib = LoadLibrary("test2dll.dll"); // If the handle is valid, try to get the function address. if (hinstLib != NULL) { printf("+ LoadLibrary Done\n"); ProcAdd1 = (MYPROC1) GetProcAddress(hinstLib, "GetInt"); ProcAdd2 = (MYPROC2) GetProcAddress(hinstLib, "SetInt"); // If the function address is valid, call the function. if ((NULL != ProcAdd1) && (NULL != ProcAdd2)) { printf("+ GetProcAddress Done\n"); fRunTimeLinkSuccess = true; printf("Return Int: %d\n",ProcAdd1()); ProcAdd2(2); printf("Return Int: %d\n",ProcAdd1()); ProcAdd2(3); printf("Return Int: %d\n",ProcAdd1()); MessageBox(NULL,"DONE",NULL,MB_OK); } else { printf("- GetProcAddress Failed\n"); error("GetProcAddress"); } // Free the DLL module. FreeLibrary(hinstLib); } else { printf("- LoadLibrary Failed\n"); error("LoadLibrary"); } // If unable to call the DLL function, use an alternative. if (!fRunTimeLinkSuccess) printf("message via alternative method\n"); return false; } void error(LPSTR lpszFunction) { CHAR szBuf[80]; DWORD dw = GetLastError(); sprintf(szBuf, "%s failed: GetLastError returned %u\n", lpszFunction, dw); MessageBox(NULL, szBuf, "Error", MB_OK); ExitProcess(dw); } Jeg får dog nogle mærkelige fejl, nå programmet har kørt... Men det henter og sætter fint værdien...
Det kan muligvis være noget i min DLL, da fejlen ikke ser ud til at være i selve EXE, programmet. Nogle ideer?
Ikke lige umiddelbart. Jeg kan selvfølgelig prøve at eksperimentere lidt i aften.
02. juli 2004 - 11:55
#10
Det ville være super! Lidt irreterende at det nu virker efter hensigten, men der kommer 3 fejl fra Windows op efter programmet er kørt...
02. juli 2004 - 22:36
#11
Jeg har fundet ud af følgende: Hvis jeg laver funktionen: int getValue() så virker det fint! Laver jeg funktionen: void setValue(int i) Så crasher den! Nogle ideer til om dette kan løses? Værdien sættes jo som sådan fint nok, men den crasher når DLL'en skal releases! Faktisk sker det efter den er releaset.
03. juli 2004 - 15:42
#12
Hm. Jeg måtte ændre det til: ProcAdd1 = (MYPROC1) GetProcAddress(hinstLib, "_GetInt@0"); ProcAdd2 = (MYPROC2) GetProcAddress(hinstLib, "_SetInt@4"); og så virkede det uden fejl. Hvordan bygger du ? Jeg bygger med: cl /LD /Fetest2dll.dll test2dll.cpp user32.lib cl test2exe.cpp user32.lib
04. juli 2004 - 02:14
#13
Jeg bygger DLL'en med: bcc32 -tWD testdll.cpp og selve exe-filen: bcc32 testexe.cpp Men hvis du har en anden løsning, gider du smide koden her? Jeg bruger jo dynamisk loading af DLL'en, og så skal jeg vel ikke bruge LIB?
04. juli 2004 - 10:55
#14
Ah med BCC så: - skulle jeg også kun bruge GetInt og SetInt - fik en fejl efter afslutning af programmet Det kigger jeg lidt videre på.
04. juli 2004 - 10:56
#15
user32.lib er nødvendig for at MS VC++ kan finde MessageBox - det har intet med din DLL at gøre
04. juli 2004 - 10:58
#16
Ok, men du får altså også en fejl når programmet er kørt "færdigt"?
04. juli 2004 - 10:59
#17
Jep
04. juli 2004 - 11:08
#18
Prøv lige med: typedef int WINAPI (*MYPROC1)(void); typedef bool WINAPI (*MYPROC2)(int);
04. juli 2004 - 11:40
#19
Det fjerner fejlen hos mig !
04. juli 2004 - 12:14
#20
Det fjerner også fejlen her! Nogen ide til hvorfor? Men anyway, du hjalp jo endnu engang, smider du et svar? :o)
04. juli 2004 - 12:57
#21
svar
04. juli 2004 - 12:58
#22
Du har erklæret dem som WINAPI i test2dll.cpp så skal de også erklæres som WINAPI i test2exe.cpp ellers kan der ske grimme ting.
04. juli 2004 - 13:06
#23
Ok, men hvis jeg fjerner WINAPI alle steder, så virker det slet ikke! Har du tilfældigvis et link, hvor jeg kan læse hvad WINAPI gør?
04. juli 2004 - 14:06
#24
WINAPI styrer calling convention. Uden WINAPI skal du bruge: ProcAdd1 = (MYPROC1) GetProcAddress(hinstLib, "_GetInt"); ProcAdd2 = (MYPROC2) GetProcAddress(hinstLib, "_SetInt");
04. juli 2004 - 14:08
#25
04. juli 2004 - 15:52
#26
Ok, men er der nogen "forskel" på at bruge WINAPI eller ProcAdd1 = (MYPROC1) GetProcAddress(hinstLib, "_GetInt"); Eller er forskellen ens?
04. juli 2004 - 15:58
#27
Ingen funktionel forskel. Men det er to forskellige måder at lave et kald på. Bare kalderen og den kaldte er enige om konventionen, så virker det. Det er også lige godt at køre i venstre side af vejen som i højre side af vejen bare man er enige i et land om hvad man gør. :-)
04. juli 2004 - 15:59
#28
Ok, men du har jo ret meget styr på C++ (har jeg efterhånden erfaret) hvilken konvention vil du bruge? Eller bruger du?
04. juli 2004 - 16:05
#29
Jeg programmerer faktisk ikke så meget C/C++ på Win32 platform. I rene C/C++ apps angiver jeg ikke nogen konvention, hvilket defaulter til __cdecl. Hvis jeg skal lave DLL'er som skal kaldes fra VB bruger jeg WINAPI (alias for __stdcall). Hvis jeg skal lave DLL'er som skal kaldes fra Java bruger jeg JNICALL (også alias for __stdcall).
04. juli 2004 - 16:07
#30
Ok, takker for info! Og igen tak for hjælpen! :o)
Kurser inden for grundlæggende programmering