Zum Inhalt springen

JNI / LoadLibrary-Problem


Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 versucht

jbyte *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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 frage

Was 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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 aussieht

Wie 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.
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...