sYnest Geschrieben 26. August 2008 Geschrieben 26. August 2008 Hallo zusammen, ich arbeite zur Zeit an einem kleinem Java Programm (1.4), in dem ich an eine Funktion aus einer bestehenden DLL heran muss. Habe probiert, dies mit Hilfe des JNI zu machen jedoch hab ich bemerkt, dass die DLL dann wissen muss das Sie mit JNI verwendet wird. Ich kann die DLL nicht ändern, habe Sie nur zur Verfügung. Kann ich auf anderem Wege an eine Funktion in dieser DLL kommen ? Mfg Danke Patrick Zitieren
Klotzkopp Geschrieben 26. August 2008 Geschrieben 26. August 2008 Schreib eine JNI-fähige DLL, die wiederum die andere DLL einbindet. Zitieren
kingofbrain Geschrieben 26. August 2008 Geschrieben 26. August 2008 Steht hier: JDK 6 Java Native Interface-related APIs & Developer Guides -- from Sun Microsystems Peter Zitieren
speedi Geschrieben 27. August 2008 Geschrieben 27. August 2008 Wenn du eine DLL über JNI anbinden willst muss diese DLL bestimmte conventionen erfüllen. Es ist zum Beispiel so, dass JAVA der DLL Java-Datentypen (z.B. jstring) übergibt, mit denen eine bereits bestehende C-DLL nicht einfach so umgehen kann wie mit einem normalen Char-array oder so. Außerdem müssen die Funktionen sich an Namenskonventionen halten. [packet_Name_der_Javaklasse_welche_die_DLL_aufruft]_[Java_Klassenname]_[Funktionsname](params...) Es ist also unumgänglich dir eine Art Zwischen-DLL zu schreiben, welche die entsprechenden Funktionen aufruft und die Übergabeparameter umwandelt. Zitieren
sYnest Geschrieben 29. August 2008 Autor Geschrieben 29. August 2008 Danke für Eure Hilfe. Ich hab mich nun mal an die Arbeit gemacht ein C++ Programm zu schreiben, dass die DLL implementiert die ich brauche und folgendes Problem ist entstanden. Die DLL wird gefunden, die Funktion findet er auch, jedoch beim Aufruf dieser Funktion entsteht ein Fehler. // CallDLL.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include "shlobj.h" #include <cstdlib> #include <iostream> #include <string> // name of the DLL to be loaded #define IPS_ENCRYPT "avpass32.dll" // <- .dll nicht vergessen using namespace std; int main(int argc, char* argv[]) { HINSTANCE hLib = NULL; hLib = LoadLibrary(IPS_ENCRYPT); if(hLib == NULL){ cout << "DLL konnte nicht geladen werden\n"; } else { cout << "DLL geladen\n"; } typedef bool (*pIpsEncrypt)( string, string, int ); pIpsEncrypt function = reinterpret_cast< pIpsEncrypt >( GetProcAddress( hLib, "IpsEncrypt" ) ); if( function != NULL ) { cout << "Funktion gefunden\n"; string s1 = "v073557"; string s2 = ""; int n1 = 8; cout << function(s1, s2, n1); } return EXIT_SUCCESS; } Zitieren
perdian Geschrieben 29. August 2008 Geschrieben 29. August 2008 jedoch beim Aufruf dieser Funktion entsteht ein Fehler.... und den behälst du für dich, damit wir weiterhin raten müssen und uns von Tatsachen nicht verwirren zu lassen brauchen?! Zitieren
dr.dimitri Geschrieben 29. August 2008 Geschrieben 29. August 2008 Hi, ich hab vor Jahren mal sowas gemacht und kann mich dran erinnern, dass das Problem daran lag, dass sich C++ Compiler nicht so ganz an die Benennungskonventionen der Funktionen halten. Frag nicht mehr was da genau war, aber bei einer reinen C DLLtrat der Fehler dann nicht mehr auf. Des weiteren ist die Ausgabe von Fehlermeldungen auf die Konsole innerhalb einer DLL doch eigentlich recht sinnfrei oder? Dim Zitieren
sYnest Geschrieben 29. August 2008 Autor Geschrieben 29. August 2008 Da wird auch nachher nichts mehr ausgegeben, nur tu ich das zur Zeit noch zu Testzwecken. Im mom. bin ich eigentlich nur dabei eine C++ Consolenanwendung zu schreiben, die auf die Funktion in der DLL zugreifen kann, sollte das der Fall sein kann ich mich ran machen und eine DLL schreiben, die das ganze macht. ... und den behälst du für dich, damit wir weiterhin raten müssen und uns von Tatsachen nicht verwirren zu lassen brauchen?! Der Fehler ist ein Speicheraddressierungsfehler. Halt n Fenster wo drin steht das ich auf Speicher zugreife, auf den ich wohl nicht zugreifen darf. Zitieren
sYnest Geschrieben 29. August 2008 Autor Geschrieben 29. August 2008 (bearbeitet) EDIT: Um das zu verdeutlichen, ich habe grade gemerkt das vor diesem Fehler noch ein anderer Auftritt der wie folgt aussieht: Debug Error! Program: W:\Haas\CallDLL\Debug\CallDLL.exe Module: File: i386\chkesp.c Line: 42 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. Ich hab auch gemerkt, dass die Funktion ausgeführt wird. Und der Fehler danach auftritt, ich kriege also was zurückgegeben bei: cout << function(s1, s2, n1); Bearbeitet 29. August 2008 von sYnest Zitieren
perdian Geschrieben 29. August 2008 Geschrieben 29. August 2008 Der Fehler ist ein Speicheraddressierungsfehler.Tja - Schade! ... sorry, aber was erwartest du bei dieser Fehlerbeschreibung anderes? Zitieren
perdian Geschrieben 29. August 2008 Geschrieben 29. August 2008 ich habe grade gemerkt das vor diesem Fehler noch ein anderer Auftritt der wie folgt aussieht:Okay, und was willst du jetzt von uns wissen? Was den Fehler ausgelöst hat bzw, ausgelöst haben könnte steht ja in der Fehlermeldung schon drin. Zeig doch mal ein wenig Eigeninitiative! Zitieren
sYnest Geschrieben 29. August 2008 Autor Geschrieben 29. August 2008 (bearbeitet) Ich zeig seit Tagen initiative. Bist du hier um zu helfen oder was gedenkst du gerade zutun? Wenn du keinen Bock darauf hast jemandem zu helfen und ihn nur darauf hinzuweisen, dass er nichts kann, bist du hier falsch. Ich will keine Lösungen oder Codeschnippsel, ich brauch nur jemanden der evtl. meinen Code darauf hin überprüft, ob da Fehler drin sind, die so ersichtlich sind. Code wurde übrigens gepostet! Okay, und was willst du jetzt von uns wissen? Was den Fehler ausgelöst hat bzw, ausgelöst haben könnte steht ja in der Fehlermeldung schon drin. Zeig doch mal ein wenig Eigeninitiative! Richtig das seh ich auch nur sehe ich nicht wo der Fehler bei mir im Code erzeugt wird, da meiner Meinung nach der Aufruf und die Deklaration ein und dieselbe Konvention benutzen Bearbeitet 29. August 2008 von sYnest Zitieren
perdian Geschrieben 29. August 2008 Geschrieben 29. August 2008 Richtig das seh ich auch nur sehe ich nicht wo der Fehler bei mir im Code erzeugt wirdDann klemm doch mal einen Debugger an, sieht dir an wo die einzelnen Statements durchlaufen werden und welche Speicherinhalte an den entsprechenden Stellen vorhanden sind. Zitieren
Bubble Geschrieben 29. August 2008 Geschrieben 29. August 2008 Ich will keine Lösungen oder Codeschnippsel, ich brauch nur jemanden der evtl. meinen Code darauf hin überprüft, ob da Fehler drin sind, die so ersichtlich sind. Auf die Fehlerquelle einer falschen Calling Convention hat schon die Fehlermeldung hingewiesen. Es wäre daher sinnvoll, wenn Du mehr zu der aufzurufenen Funktion sagen würdest, insbesondere was die Dokumentation der Funktion zu Aufrufkonvention, Rückgabewert und erwarteten Parametern und ihrem Typ sagt. Ich halte es nämlich für unwarscheinlich, dass eine DLL-Schnittstelle C++-String-Objekte als Parameter erwartet, ich würde eher auf C-Strings tippen. Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 Ne, es gibt keine Dokumentation. Das Ding is wohl schon sau alt. Einziger Anhaltspunkt, den ich habe ist die Verwendung von der DLL in Centura. In Centura: Rückgabewert: Boolean Parameter: Receive String, Receive String, Number Folglich: Rückgabewert: Bool(ean) Parameter: String(-Pointer), String(-Pointer), int Zitieren
Guybrush Threepwood Geschrieben 1. September 2008 Geschrieben 1. September 2008 (bearbeitet) Dann mach aus den std:strings die du der Funktion übergibst mal char Arrays (wie Bubble gesagt hat) und schau mal was passiert, wobei das eigentlich egal sein sollte solange die Funktion die übergebenen Strings nicht verändern soll. Okay, und was willst du jetzt von uns wissen? Was den Fehler ausgelöst hat bzw, ausgelöst haben könnte steht ja in der Fehlermeldung schon drin. Zeig doch mal ein wenig Eigeninitiative! Warum postest du hier eigentlich :confused: EDIT: Hast du zu der Dll noch andere Dateien, z.b. .lib? Bearbeitet 1. September 2008 von Guybrush Threepwood Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 ich sag mal so: Den Test mit den Chararrays hab ich eben gemacht. Übergebe ich Strings so wies nun ist, dann gibt mir die Methode ein true zurück und wird erfolgreich ausgeführt wenn man von diesem Conventionsfehler und den Aspekt, dass der String von dem ich einen Pointer an die DLL Funktion übergebe nicht mehr Aufrufbar ist absieht. Mit übergabe von Chararrays wird die Methode nicht erfolgreich ausgeführt was mich dazu bringt zu denken, dass das wohl falsch ist. Nicht das man mich falsch versteht, mich stört das die Methode ausgeführt wird und mir sogar ein True zurück gibt, was bedeutet, dass das Passwort verschlüsselt worden ist ich aber im nachhinein nicht mehr auf den String zugreifen kann, der ja verändert wurde durch die DLL Funktion. Man sieht das gut am Anhang "Fehler.jpg": Das passiert unmittelbar nach ausführen des Programms, dieser Fehler tritt quasi in der DLL Funktion auf. Wenn ich den Conventionsfehler ignoriere ich habe ich dann, wenn man der Console folgt iwie nen erfolgreichen Aufruf der Methode. (Fehler2.jpg) Grundlegend hab ich einen String, auf den ich einen Pointer gesetzt habe, den ich an die Funktion übergebe. Dieser String (nicht der Pointer) ist nach Aufruf der Funktion nicht mehr aufrufbar. Da ich nicht weiss was die Funktion wirklich macht und es keine Doku gibt hab ich keine Ahnung warum das so ist. Mein Programm ist zur Zeit in C++ und so wies aussieht findet die DLL Funktion wohl diese C++ Strings *******e. Daher vllt der Conventionsfehler. Jedoch wüsste ich nicht was sich bei der Verwendung von C Strings ändern sollte. Um auf die Frage der anderen Daten zu antworten: Ich hab nur die DLL und leider gottes NICHTS anderes, bzw. noch den Aufruf dieser Funktion aus einem Centuraprogramm, was mir aber nicht weiterhilft. Zur Übersicht aktueller Code: // CtoAvpass32DLL.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include "shlobj.h" #include <cstdlib> #include <iostream> #include <string> // name of the DLL to be loaded #define IPS_ENCRYPT "avpass32.dll" // <- .dll nicht vergessen using namespace std; int main(int argc, char* argv[]) { HINSTANCE hLib = NULL; hLib = LoadLibrary(IPS_ENCRYPT); if(hLib == NULL){ cout << "DLL konnte nicht geladen werden\n"; } else { cout << "DLL geladen\n"; } typedef bool (*pIpsEncrypt)( string *, string *, int ); pIpsEncrypt function = reinterpret_cast< pIpsEncrypt >( GetProcAddress( hLib, "IpsEncrypt" ) ); if( function != NULL ) { cout << "Funktion gefunden\n"; string s1 = ""; string s2 = ""; string * p1 = &s1; string * p2 = &s2; int n1 = 8; try { if(function(p1, p2, n1) == 1) { cout << "Verschlüsselung erfolgreich!" << endl; cout << s2; //FUNTIONIERT NICHT } } catch (...) { cout << "Catchbereich!" << endl; } } return EXIT_SUCCESS; } Zitieren
TDM Geschrieben 1. September 2008 Geschrieben 1. September 2008 Dieser String (nicht der Pointer) ist nach Aufruf der Funktion nicht mehr aufrufbar. Da ich nicht weiss was die Funktion wirklich macht und es keine Doku gibt hab ich keine Ahnung warum das so ist. if(function(p1, p2, n1) == 1) { cout << "Verschlüsselung erfolgreich!" << endl; cout << s2; //FUNTIONIERT NICHT } btw: typedef bool (*pIpsEncrypt)( string *, string *, int ); wtf?! Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 btw: typedef bool (*pIpsEncrypt)( string *, string *, int ); wtf?! Das ist nicht hilfreich. Musst mir schon sagen wo dein Problem ist. Zitieren
TDM Geschrieben 1. September 2008 Geschrieben 1. September 2008 Das ist nicht hilfreich. Musst mir schon sagen wo dein Problem ist. Naja, typedef ist etwas unüblich, ich hätte hier mehr an "extern" oder declspec gedacht. Aber egal. Außerdem ist es komisch, wenn die Funktion den Rückgabetyp bool hat und da wird auf == 1 geprüft, aber naja. kommst du nicht an den Quelltext ran? Weil im Beispielcode funktioniert da ja schon was nicht... Zitieren
Guybrush Threepwood Geschrieben 1. September 2008 Geschrieben 1. September 2008 Das ist nicht hilfreich. Musst mir schon sagen wo dein Problem ist. Das Progblem ist das das ziemlicher Unsinn ist Wenn die Funktion die übergebenen Strings verändert, was ja wohl der Fall ist wenn einer davon verschlüsselt wird, dann kannst du keinen std:string übergeben wenn eigentlich ein C-String (also ein Char Array) erwartet wird, weil du somit zwar einen Pointer auf das interne Char Array des std::string Objects erhälst, dieses aber nicht ändern darfst weil du somit das Obejct zerstörst. Versuch es mal so: typedef bool (*pIpsEncrypt)( char*, char*, int ); char s1[100]; char s2[100]; // strcpy (s1,"Test"); //um etwas in s1 zu schreiben if(function(s1, s2, n1) == 1) { } [/PHP] Hast du eine Idee wofür der 3. Parameter ist? Ein Problem bei der obigen Variante ist wenn die Funktion etwas in einen der beiden Strings schreiben will was mehr als 100 Zeichen (oder halt soviele wie du reserviert hast) hat. Kann es sein das der dritte Parameter die länge der Felder angeben soll? Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 Ja stimmt schon, sind aber kleinigkeiten, ich kann die Funktion auch auf True prüfen mit dem selben ergebnis ;D An den Quelltext komm ich wie gesagt nicht, aber ich kann versichern, dass die Methode korrekt funktioniert, da ich eine Centura-Anwendung habe, die diese Funktion auch benutzt - einwandfrei. Naja, typedef ist etwas unüblich, ich hätte hier mehr an "extern" oder declspec gedacht. Aber egal. ...besagt, dass das so funktionieren kann ? Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 Auf die Frage bezüglich des dritten Parameters kann ich leider keine Antwort geben. Hatte auch vermutet, dass es was mit der Länge zutun hat, aber spielen mit der Zahl hat keine Wirkung gezeigt. Zitieren
sYnest Geschrieben 1. September 2008 Autor Geschrieben 1. September 2008 Neuer Code: //typedef bool (*pIpsEncrypt)( string *, string *, int ); typedef bool (*pIpsEncrypt)( char *, char *, int ); pIpsEncrypt function = reinterpret_cast< pIpsEncrypt >( GetProcAddress( hLib, "IpsEncrypt" ) ); if( function != NULL ) { cout << "Funktion gefunden\n"; //string s1 = ""; //string s2 = ""; //string * p1 = &s1; //string * p2 = &s2; char s1[100]; char s2[100]; int n1 = 8; try { if(function(s1, s2, n1)) { cout << "Verschlüsselung erfolgreich!" << endl; } else { cout << "Verschlüsselung nicht erfolgreich!" << endl; } cout << s2; //FUNTIONIERT NICHT } catch (...) { cout << "Catchbereich!" << endl; } } Was nun passiert ist, dass die Fehlermeldung bezüglich der Convention nicht mehr da ist, was gut ist, jedoch wird nun in der Methode ein Fehler erzeugt, der mich direkt in den Catchbereich katapultiert, ich also keine Ausgabe mehr hab was die Verschlüsselung angeht. if(function(s1, s2, n1)) { // BRICHT ALSO HIER AB cout << "Verschlüsselung erfolgreich!" << endl; } else { cout << "Verschlüsselung nicht erfolgreich!" << endl; } Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.