Zonbléou Geschrieben 9. April 2009 Teilen Geschrieben 9. April 2009 Hallo, ich habe eine Frage die sich auf java, jni/jna, c/c++ bezieht. Kann mir jemand diese Frage antworten? Ich habe es soweit bis fast der letzte Punkt wo ich blockiert bin. Ich will die C-DLL Methoden in java aufrufen. Soweit habe ich das ganze gebaut bis die dlls geladen. Jetzt versuche ich die Methoden aufzurufen und ich kriege Fehlermeldung wie folgt An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0adc18f5, pid=2060, tid=3468 # # Java VM: Java HotSpot Client VM (1.6.0_03-b05 mixed mode) # Problematic frame: # C [DetSys_001.dll+0x18f5] # # An error report file with more information is saved as hs_err_pid2060.log # # If you would like to submit a bug report, please visit: # HotSpot Virtual Machine Error Reporting Page Hier ist meine Implementierung: HINSTANCE hIns; pFunc pFn; hIns = LoadLibraryEx("C:\\Dokumente und Einstellungen\\SBX825\\Desktop\\Rohdata\\DetSys_001", NULL, DONT_RESOLVE_DLL_REFERENCES); printf("AddressDll %d\n", hIns); printf("LoadLibrary: %d\n", GetLastError()); if(hIns) pFn = (pFunc)GetProcAddress(hIns, "_mcbe_RechneMitZeile"); printf("AddressFunc %d\n", pFn); printf("LoadLibrary: %d\n", GetLastError()); pFn != NULL; pFn(3); //pFunc(input64); FreeLibrary(hIns); Vielen Dank im voraus. Zonbléou Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. April 2009 Teilen Geschrieben 9. April 2009 DONT_RESOLVE_DLL_REFERENCES klingt nach Ärger. Ich hoffe, du hast einen wirklich guten Grund dafür. Wenn es ein Problem mit den Abhängigkeiten gibt, dann ist DONT_RESOLVE_DLL_REFERENCES die "Augen zu"-Lösung. Du siehst das Problem nicht mehr, aber es ist immer noch da. Es knallt dann halt später. Welche Ausgaben erzeugen deine printfs? Und was sagt die Dokumentation der Funktion _mcbe_RechneMitZeile über die Parameter? Bist du sicher, dass sie mit 3 etwas anfangen kann? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 9. April 2009 Autor Teilen Geschrieben 9. April 2009 Hi, So mit LoadLibrary() werden die Dll die Abhängigkeiten zu den anderen Dll haben nicht geladen. Die nächste Möglichkeit ist diese Methode LoadLibraryEx() die drei Parameter erwartet. Damit habe ich zu mindestens die Adresse der Dll und die Methode ausgeben können. input64 ist ein Parameter der Methode _mcbe_RechneMitZeile(). Jetzt habe ich die Implementierung wie folgt versuchtjbyte *input64 = (*env)->GetByteArrayElements(env, jarr, 0); //Eine Instanz zum Laden der DLL und Zugriff auf Methoden definieren HINSTANCE hIns; pFunc pFn; hIns = LoadLibraryEx("C:\\Dokumente und Einstellungen\\SBX825\\Desktop\\Rohdata\\DetSys_001", NULL, DONT_RESOLVE_DLL_REFERENCES); printf("AddressDll %d\n", hIns); printf("LoadLibrary: %d\n", GetLastError()); if(hIns) pFn = (pFunc)GetProcAddress(hIns, "_mcbe_RechneMitZeile"); printf("AddressFunc %d\n", pFn); printf("LoadLibrary: %d\n", GetLastError()); pFn != NULL; pFn(input64); input64 bekommt Array Werte auf Java Seite. Ich kann hier leider keine Ausgabe in der Consol mit printf auf pFn(input64) machen, weil die Methode _mcbe_RechneMitZeile hat ein void als Rückgabe Typ. Die Ausführen gibt keine Fehlermeldung und zeig auch nichts. Wie kann ich jetzt testen, dass mein Aufruf wirklich funktioniert? Danke. Z. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. April 2009 Teilen Geschrieben 9. April 2009 So mit LoadLibrary() werden die Dll die Abhängigkeiten zu den anderen Dll haben nicht geladen. Die nächste Möglichkeit ist diese Methode LoadLibraryEx() die drei Parameter erwartet. Damit habe ich zu mindestens die Adresse der Dll und die Methode ausgeben können.Damit ignorierst du nur das Problem, dass die Abhängigkeiten der DLL nicht erfüllt sind, du löst es nicht. Wie kann ich jetzt testen, dass mein Aufruf wirklich funktioniert?Wenn die Funktion nichts zurückgibt und auch sonst keine Seiteneffekte hat, dann kann die Wirkung sich nur im Inhalt des übergebenen Arrays zeigen. Du musst doch irgendeine Vorstellung davon haben, was die Funktion tut. Was sagt denn die Dokumentation der Funktion? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 9. April 2009 Autor Teilen Geschrieben 9. April 2009 Hallo, ich habe jetzt keine Ideen mehr. Das stimmt das was Du sagst wegen vergenes Problem, aber wie kann ich effizient das Problem lösen? Hast Du vielleicht eine Idee oder eine Funktion die ich benutzen kann? Kannst Du mir die geben? Die Funktion bekommt einen Array von Werten rechnet und gibt das Ergebnis zurück. Brauche ich noch eine zusätliche Implementierung in meiner Datei? Danke Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. April 2009 Teilen Geschrieben 9. April 2009 Die Funktion bekommt einen Array von Werten rechnet und gibt das Ergebnis zurück. Dann bring das Ergebnis doch mit NewByteArray/SetByteArrayRegion wieder nach Java zurück. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 9. April 2009 Autor Teilen Geschrieben 9. April 2009 Hi, wie baut sich diese Funktion auf? oder wie macht man das? Kannst Du mir ein Bsp. geben? Danke Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. April 2009 Teilen Geschrieben 9. April 2009 Hi, wie baut sich diese Funktion auf? oder wie macht man das? Kannst Du mir ein Bsp. geben? Der erste Reflex sollte sein, selbst nach solchen Informationen zu suchen. Ich kann dir kein Beispiel geben, weil es sehr lange her ist, dass ich mich mit JNI beschäftigt habe. Aber Google zeigt mir, dass Sun Beispiele hat. Wer hätte das gedacht? http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jnistring.html Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 20. April 2009 Autor Teilen Geschrieben 20. April 2009 Hallo, könnte mein Programm bis jetzt immer noch nicht zum laufen bringen. Wenn ich die NewByteArray/SetByteArrayRegion Methoden einbaue dann kriege ich die fehlermeldung, ich bin nicht in Benutzung von Structure oder Union. So sieht mein Programm endlich aus: HINSTANCE hIns; pFunc pFn; hIns = LoadLibraryEx("C:\\Dokumente und Einstellungen\\SBX825\\Desktop\\Rohdata\\DetSys_001", NULL, DONT_RESOLVE_DLL_REFERENCES); printf("AddressDll %d\n", hIns); printf("LoadLibrary: %d\n", GetLastError()); if(hIns) pFn = (pFunc)GetProcAddress(hIns, "_mcbe_RechneMitZeile"); printf("AddressFunc %d\n", pFn); printf("LoadLibrary: %d\n", GetLastError()); printf("%d\n", pFn(input64)); FreeLibrary(hIns); Ich lasse das laufen und ich kriege diese Fehlermeldung: # # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0adc18f5, pid=4076, tid=3440 # # Java VM: Java HotSpot(TM) Client VM (1.6.0_03-b05 mixed mode) # Problematic frame: # C [DetSys_001.dll+0x18f5] # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # Vielleicht kann mir jemand dabei helfen. Zonbléou Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 20. April 2009 Teilen Geschrieben 20. April 2009 Wenn ich die NewByteArray/SetByteArrayRegion Methoden einbaue dann kriege ich die fehlermeldung,Wenn du weder die Fehlermeldung noch den Code dazu zeigst, wird sich daran auch nichts ändern. # C [DetSys_001.dll+0x18f5]Das Programm stürzt mit einem ungültigen Speicherzugriff ab, in der DLL, die du da lädst. Möglicherweise ist der Parameter nicht korrekt. Möglicherweise sind Abhängigkeiten der DLL nicht aufgelöst, diese Prüfung hast du ja mit DONT_RESOLVE_DLL_REFERENCES abgeschaltet. Beantworte bitte folgende Fragen: Warum ist DONT_RESOLVE_DLL_REFERENCES da immer noch drin?Welche Werte geben deine printfs aus?Welchen Wert hat input64 vor dem Aufruf von pFn?Was sagt die Dokumentation der Funktion _mcbe_RechneMitZeile darüber, wie der Parameter beschaffen sein muss? Fast alle diese Fragen habe ich dir schon einmal gestellt, und du hast sie nicht beantwortet. Solange du das nicht tust, kann ich dir nicht weiterhelfen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 21. April 2009 Autor Teilen Geschrieben 21. April 2009 Hallo, bevor ich meine Fragen stelle muss ich erst was versuchen. Ich denke ich weiss wirklich nicht wie ich weiter kommen kann. Ich kann mich nur auf ihre Unterstütznug verlassen. Ich muss jetzt versuchen die Fragen zu beantworten. Warum ist DONT_RESOLVE_DLL_REFERENCES da immer noch drin? Erstens habe ich versucht das Laden der Dll mit LoadLibrary(), die Methode die Maindll und die abhängigen Dll mitlädet und initialisiert. Ich kann damit die Dll nicht laden da weder die Adresse der dll noch die der Methode in dll könnte gefunden werden. Ich habe aus der MSDN gelesen, dass es noch eine die LoadLibraryEx() gibt, die die dll laden kann. Aber diese braucht mindestens drei parameter. Deswegen war ich dabei alles zu probieren. jetzt habe ich den Code so geändert JNIEXPORT void JNICALL Java_triangleberechner_Triangulationsberechnung__1mcbe_1RechneMitZeile (JNIEnv *env, jobject obj, jbyteArray jarr) { // Größe des übergebenen Array ermitteln jsize len = (*env)->GetArrayLength(env, jarr); // Pointer zum Zugriff auf Arrayelemente initialisieren jbyte *input64 = (*env)->GetByteArrayElements(env, jarr, 0); //Eine Instanz zum Laden der DLL und Zugriff auf Methoden definieren HINSTANCE hIns; pFunc pFn; hIns = LoadLibraryExA("DetSys_001.DLL", NULL, DLL_PROCESS_ATTACH); // hIns = LoadLibrary("DetSys_001"); printf("AddressDll %d\n", hIns); printf("LoadLibrary: %d\n", GetLastError()); if(hIns) pFn = (pFunc)GetProcAddress(hIns, "_mcbe_RechneMitZeile"); printf("AddressFunc %d\n", pFn); printf("LoadLibrary: %d\n", GetLastError()); //pFn(input64); //printf("%d \n", (pFunc)(input64)); FreeLibrary(hIns); (*env)->ReleaseByteArrayElements(env, jarr, input64, 0); So nächstes Welche Werte geben deine printfs aus? Wenn ich den Aufruf //pFn(input64); auskommentiere, dann kann ich die Adresse der Dll und der aufzurufenden Methode lesen. Das kann ich mit dem Dependency Walker nach Korrektheit der Adressen prüfen. Mit dem Aufruf von pFn(input64); sehe ich nicht in der Konsole und dann wird dieser Fehler Report generiert # # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0adc18f5, pid=4076, tid=3440 # # Java VM: Java HotSpot Client VM (1.6.0_03-b05 mixed mode) # Problematic frame: # C [DetSys_001.dll+0x18f5] # # If you would like to submit a bug report, please visit: # HotSpot Virtual Machine Error Reporting Page # Werte von input64 Welchen Wert hat input64 vor dem Aufruf von pFn? Auf der Java Seite erzeuge ich einen Array der so aussieht byte[] input64 = {12, 32, 45, 34, 54, 65, 4, 3, 57, 0, 43, 5, 1, 34, 23, 45}; Letzte frageWas sagt die Dokumentation der Funktion _mcbe_RechneMitZeile darüber, wie der Parameter beschaffen sein muss? Ich versuche hier die Implemntierung der Methode aus C mit zu kopieren. Ich hoffe es wird nicht zu viel Arbeit für dich zum Anschauen sein. ich habe ansonsten keine richtige Dokumentation dazu. Hier die Implementierung // Entfernt, Rechte unklar (Klotzkopp). ich habe heute aus MSDN gelesen, dass diese LoadLibrary erfordert ein paar Sachen wie: Linker Coredll.lib, ich habe auf meinem System gesucht und könnte keine Coredll.lib finen, kann es sein, dass es daran liegt? Wenn ja wie Schaffe ich das? Google könnte mir nicht helfen. Danke für die weiter Ideen. Zonbléou Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 21. April 2009 Teilen Geschrieben 21. April 2009 Ich kann damit die Dll nicht laden da weder die Adresse der dll noch die der Methode in dll könnte gefunden werden.Ich hatte schon gesagt, dass DONT_RESOLVE_DLL_REFERENCES für dieses Problem keine Lösung ist. Damit wird die DLL zwar geladen, wenn aber eine der Abhängigkeiten gebraucht wird, gibt es einen Absturz. hIns = LoadLibraryExA("DetSys_001.DLL", NULL, DLL_PROCESS_ATTACH);DLL_PROCESS_ATTACH ist kein gültiges Flag für LoadLibraryEx. DLL_PROCESS_ATTACH hat den Wert 1, genau wie DONT_RESOLVE_DLL_REFERENCES. Dasselbe Problem wie bei LoadLibrary. Werte von input64 Auf der Java Seite erzeuge ich einen Array der so aussiehtWie lautet die Adresse des Arrays auf der C-Seite? Und woher nimmst du diese Werte? Hast du dir die ausgedacht? Bist du sicher, dass mcbe_RechneMitZeile mit diesen Daten etwas anfangen kann? Benutz bitte mal zum Testen ein Array von Nullen. Ich versuche hier die Implemntierung der Methode aus C mit zu kopieren. Ich hoffe es wird nicht zu viel Arbeit für dich zum Anschauen sein. ich habe ansonsten keine richtige Dokumentation dazu.Eine DLL ohne Dokumentation ist praktisch nutzlos. Ein grundlegendes Problem hier ist, dass sich innerhalb der Funktion in C nicht mehr feststellen lässt, wie groß das Array war. Diese Information muss also irgendwie im Array selbst stecken. Hier die ImplementierungÜberprüfe bitte dringend, ob du das Copyright für diesen Code hast und damit berechtigt bist, ihn hier zu veröffentlichen. Falls nicht, gib mir bitte umgehend Bescheid. ich habe heute aus MSDN gelesen, dass diese LoadLibrary erfordert ein paar Sachen wie: Linker Coredll.lib, ich habe auf meinem System gesucht und könnte keine Coredll.lib finen, kann es sein, dass es daran liegt?Nein. Ich weiß auch nicht, woher du das hast. LoadLibrary erfordert kernel32.lib. Wenn du die nicht hättest, hättest du deine C-DLL gar nicht erstellen können. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 22. April 2009 Autor Teilen Geschrieben 22. April 2009 Hallo, jetzt muss ich eigentlich mit dem projekt aufhören. Der Programmcode sollte normalerweise nicht veröffentlich werden, aber ich war stark am Suchen einer Lösung und habe deswegen alles das vergessen. Sorry! Ich habe jetzt versucht alle abhängigen Dll oder Bibliotheken im Adressraum des Processes zu laden. Alle Adressen könnten gelesen werden. Der Aufruf meiner Methode: pFn(input64); führt nicht mehr zu Programmabstürzt. Trotzdem habe ich keine Ergebnisse mit nur 0 im meinem Array. ich gehe davon aus, dass die Deklaration von meinem input64 auf der Wrapper Seite ist nicht richtig. So habe ich deklariert: typedef void (*pFunc)(unsigned char*); jbyte *input64 = (*env)->GetByteArrayElements(env, jarr, 0) env und jarr kommen von dem Parameter Liste meiner importierte Methode. Da bin mir nicht ganz sicher, ob es so sein soll. Danke für die Mitarbeit. Trotzdem habe ich was gelernt. Zombléou. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 24. April 2009 Autor Teilen Geschrieben 24. April 2009 Hallo meinen Herrn, ich dachte mit dem Projekt muss ich aufhören aber es ist nicht einfach. Ich sehe schon das Ende nur fehlt es mir die Ergebnisse. Bei meinen letzten Recherchen habe ich gemerkt, dass die Ergebnisse sind normalerweise in einer anderen Dll abgelegt. Diese sind in Ergebnisvariablen gespeichert. Diese Variablen mussen jetzt für die Bewertung zum Java Programm geholt werden. Ich wende mich noch an dich falls ich die richtige Implementierung nicht finde. Danke im voraus. Zonbléou Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Zonbléou Geschrieben 28. April 2009 Autor Teilen Geschrieben 28. April 2009 Hallo, ich hätte noch eine Frage. wie holt man die Ergebnisvariablen aus einer DLL nach Java? Nach der Berechnung sind meine Ergebnisse in Variablen in der DLL gespeichert. Mfg. Z. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
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.