Fremde DLL einbinden, Funktionen bekannt, keine Header, keine Doku
-
Hallo zusammen,
ich möchte eine xy.dll (Treiber-DLL in diesem Fall) in Visual C++ einbinden. Ich habe viel im Internet gelesen und bin am Ende. Ich bin total verwirrt.
Was irgendwo Sinn macht, ist, das man die Funktionen der dll über Zeiger ansprechen muss, wenn keine Header vorhanden ist. Nur wie mache ich das?
Die Funktion die ich aus der DLL brauche schaut so aus:
public static native int[] getConnectedBurnedInIDs();
und evtl. noch
public static native void init();
wäre schön wenn jemand n vernünftigen Link hätte oder mit nen 10-Zeiler
zeigt, wie das mit den Zeigern auf Funktionen einer dll datei geht und wie man die dll einbindet.
Ich bin in C++ mit seiner Sprache ganz fit, Zeiger bereiten mir keine Probleme.
Herzlichen Dank.
-
Schon mal Stichwörter: LoadLibrary (zum Laden der Dll, wer hätte das gedacht
), GetProcAddress (zum Holen der Adresse einer bestimmten Funktion=>Funktionszeiger).
Hab grad keine Zeit, vielleicht stell ich später ein kleines Beispiel zusammen... (oder du suchst nach den genannten Funktionen, da sollte sich schnell was finden)
-
Vielen Dank, habe auch was gefunden:
typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT); ... HINSTANCE hDLL; // Handle to DLL LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer DWORD dwParam1; UINT uParam2, uReturnVal; hDLL = LoadLibrary("MyDLL"); if (hDLL != NULL) { lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "DLLFunc1"); if (!lpfnDllFunc1) { // handle the error FreeLibrary(hDLL); return SOME_ERROR_CODE; } else { // call the function uReturnVal = lpfnDllFunc1(dwParam1, uParam2); } }
Leider sagt VC++ beim übersetzen das er HINSTANCE nicht kennt. Habe die windows.h eingebunden und ein 32-Bit Consolen Anwendungs Projekt gemacht.
-
Folgendes geht nicht:
#include <stdio.h> #include <conio.h> #include <windef.h> int main(int argc, char* argv[]) { HINSTANCE hDLL = NULL; hDLL = LoadLibrary("wandel.dll"); return 0; }
Da bekomme ich
c:\programme\microsoft sdks\windows\v6.0a\include\winnt.h(5545) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'ContextRecord'
-
Sorry, #include <windows.h> muss hin, sonst nix...
-
Rex75 schrieb:
Sorry, #include <windows.h> muss hin, sonst nix...
Das heißt, alle Probleme sind jetzt gelöst?
-
Hi, danke für die Nachfrage.
Das Programm funktioniert auf der Maschine wo ich es kompiliert habe, aber wenn ich die exe auf einen anderen Rechner starte, kommt:
"Die Anwendung konnte nicht gestartet werden, weil die Anwenungskonfiguration nicht korrekt ist. Zur Problembehebung sollten Sie die Anwendung neu installieren."
Hmmmm, hab schon gegoogelt und Framework 3.5 und Microsoft Visual C++ 2005 Redistributable Package (x86) installiert. Selbe Fehlermeldung.
Habe VC++ 2008 Express verwendet zum komplilieren. Hier nochmal mein Quellcode, falls es jemanden interessiert:
#include <windows.h> int main(int argc, char* argv[]) { typedef INT (CALLBACK* LPFNDLLFUNC1)(); LPFNDLLFUNC1 lpfnDllFunc1; // INT uReturnVal; HINSTANCE hDLL = NULL; hDLL = LoadLibrary("c:/Programme/James/bin/FunctionDriver.dll"); if (hDLL != NULL) { lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "getConnectedBurnedInIDs"); if (!lpfnDllFunc1) { // handle the error FreeLibrary(hDLL); return -2; } else { // call the function return lpfnDllFunc1(); } } else { return -1; } }
Achja, ein Problem hab ich doch, denke ich, der Rückgabewert ist ein int-Array, habe versucht es bei typedef zu definieren mit int[], aber das geht nicht. Jaja, C++ ist schon etwas länger her bei mir. Muss mir die Arrays nochmal anschaun denk ich.
Danke schonmal. Lieben Gruß.
-
Du musst dann ein int* als Rückgabewert nehmen.
Hast du das Programm im Debug compiliert und dann auf einem anderen Rechner ausgeführt? Das geht nicht (bzw die Debug Versionen der DLLs werden nur installiert, wenn du das entsprechende Studio installierst).
-
[...] Microsoft Visual C++ 2005 Redistributable Package (x86)[...]
[...] Habe VC++ 2008 Express verwendet zum komplilieren [...]
Versuche doch einmal das Microsoft Visual C++ 2008 Redistributable Package (x86) auf dem Zielrechner zu installieren.
-
Danke, habe auf Release umgestellt, jetzt geht die Ausführung.
Oh man, es ist so lange her
Wie kann ich den Rückgabewert des Programmes irgendwie unter der Kommandozeile abfangen, bzw. abfragen?
Danke.
-
Hab jetzt schon gefunden, wie man mit hilfe von Errolevel in Dos-Batch Dateien das abfangen kann. Jetzt habe ich aber ein anderes Problem. Er findet die Funktionen einfach nicht.
Hier der Quelltext:
#include <windows.h> #using <System.dll> using namespace System; using namespace System::IO; int main(int argc, char* argv[]) { typedef INT* (CALLBACK* LPFNDLLFUNC1)(); LPFNDLLFUNC1 lpfnDllFunc1; typedef VOID (CALLBACK* LPFNDLLFUNC2)(); LPFNDLLFUNC2 lpfnDllFunc2; INT* uReturnVal; HINSTANCE hDLL = NULL; hDLL = LoadLibrary("c:/Programme/Tool/Driver.dll"); if (hDLL != NULL) { lpfnDllFunc2 = (LPFNDLLFUNC2)GetProcAddress(hDLL, "_DRV_init"); if (!lpfnDllFunc2) { // handle the error FreeLibrary(hDLL); Console::WriteLine("Init Funktionsaufruf fehlerhaft"); return -3; } else { // call the function lpfnDllFunc2(); Console::WriteLine("Init Funktionsaufruf erfolgreich"); } lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "_DRV_getBurnedInIDs"); if (!lpfnDllFunc1) { // handle the error FreeLibrary(hDLL); Console::WriteLine("ID Functionsaufruf fehlerhaft"); return -2; } else { // call the function uReturnVal = lpfnDllFunc1(); // ToDo: uReturnVal auswerten Console::WriteLine("ID Functionsaufruf erfolgreich"); return 0; } } else { Console::WriteLine("DLL nicht gefunden"); return -1; } }
Und hier mit Hilfe von Nasi von Stefan Schnell. Ein Programm um die Funktionen von einer DLL herauszufinden:
// Function _DRV_init@0------------------------------------------- /** * * * @param * * @return */ public static int _DRV_init@0(...) { int res = 0; IntCall _DRV_init@0 = new IntCall("driver.dll", "_DRV_init@0"); res = _DRV_init@0.executeCall(new Object[] {...}); _DRV_init@0.destroy(); return res; }
// Function _FBD_getConnectedBurnedInIDs@4------------------------ /** * * * @param * * @return */ public static int _DRV_getBurnedInIDs@4(...) { int res = 0; IntCall _DRV_getBurnedInIDs@4 = new IntCall("driver.dll", "_DRV_getBurnedInIDs@4"); res = _DRV_getBurnedInIDs@4.executeCall(new Object[] {...}); _DRV_getBurnedInIDs@4.destroy(); return res; }
Ich versuch praktisch mit
lpfnDllFunc2 = (LPFNDLLFUNC2)GetProcAddress(hDLL, "_DRV_init");
die folgende Funktion der DLL aufzurufen:
public static int _DRV_init@0(...)
Wäre schön wenn mir jemand helfen könnte, danke.