JNI: C-->Java : Methode mit String-Parameter

Status
Nicht offen für weitere Antworten.

Leroy42

Top Contributor
Ich schreibe gerade ein Java-Workbench, mit der ich einen
C-Code, der später in einer MCU sein Unwesen treiben wird,
komfortabel auf Herz und Nieren prüfen kann.

Ich habe jetzt ein Problem beim Aufruf einer Info-Methode
an das Java-Programm (das gewissermaßen den IO-Anteil simuliert)
die einfach nur einen String übergeben soll.

Hier der reduzierte Code

Code:
void infoJava() {
#if JAVA
#	if 1
		jclass cls = (*theEnv)->GetObjectClass(theEnv, theObj);
		jmethodID mid = (*theEnv)->GetStaticMethodID(theEnv, cls, "sinfo", "(Ljava/lang/String;)V");
		(*theEnv)->CallStaticVoidMethod(theEnv, theObj, mid, (*theEnv)->NewStringUTF(theEnv, infoBuf));
#	else
		puts(infoBuf);
		fflush(stdout);
#	endif
#endif
}

Der Aufruf der Java-Methode sinfo(String info) erzeugt nach einer
gewissen Zeitspanne einen Crash der JVM. Nicht direkt reproduzierbar,
da der Methodenaufruf einige Male funktioniert bevor er zum Crash führt. :(

Schreibe ich im obigen Code #if 0 (Ich gebe den String also einfach via puts aus,
gibt es keine Probleme :D , womit ich also Fehler in anderen Codestellen ausschließen kann.

Da ich später allerdings innerhalb des Java-Programms auf die von C gesendeten
Informationen reagieren will, brauche ich auch die C-->Java Kommunikation.

Die Variablen theEnv und theObj sind die beim ersten Aufruf einer Methode von Java--->C
gespeicherten Variablen env und obj.

Weiß jemand Rat?
 
G

Gast

Gast
Hi,
einen direkten Fehler kann ich hier nicht erkennen. Aber du solltest eventuell einfach ein paar Sicherheitsprüfungen reinnehmen.
Sowohl die Klasse als auch die MethodenId können schließlich ungültig sein, prüf die lieber auf != 0.
 

Murray

Top Contributor
Woher kommt denn infoBuf? Kann es evtl. passieren, dass die Varibale bei manchen Aufrufen 0 (oder nicht initialisiert ist)?
 

thE_29

Top Contributor
Dein Methodenkopf ist aber schon static?

also public static void sinfo(String s)


Sieht der so aus?
 

Leroy42

Top Contributor
Gast hat gesagt.:
Sowohl die Klasse als auch die MethodenId können schließlich ungültig sein, prüf die lieber auf != 0.

Ok, werd' ich machen, aber die ersten Aufrufe funktionieren ja problemlos.

Murray hat gesagt.:
Woher kommt denn infoBuf? Kann es evtl. passieren, dass die Varibale bei manchen Aufrufen 0 (oder nicht initialisiert ist)?

infoBuf steht außerhalb der Funktionen (Ich glaube das heißt in C dann static!?) und wird
von verschiedenen Stellen gefüllt.

thE_29 hat gesagt.:
Dein Methodenkopf ist aber schon static?

also public static void sinfo(String s)


Sieht der so aus?

Ja, sicher! Wie gesagt, ein paar Mal funktioniert der Aufruf ja auch problemlos.


Hat jemand eine Idee, wie ich einen String anders an Java übergebe und Java
irgendwie drauf aufmerksam mache, daß ein neuer Infostring vorliegt?
 

thE_29

Top Contributor
Mh..

Vielleicht ziehts ihm ja bei dem newStringUTF auf, weil im String nix drinnen ist!

oder er mit keinem \0 aufhört!

Ich würd mal debug einbauen, also ausgeben ob die Methode einen Werte != 0 hat!

Bzw, alles einen Wert != 0 hat und das newStringUtf vorher aufrufen und zwischenspeichern!
 

Leroy42

Top Contributor
Ich habe jetzt, gemäß euren Vorschlägen, ein paar Ausgabeanweisungen eingebaut.

Code:
void infoJava() {
#if JAVA
#	if 1
		jclass cls = (*theEnv)->GetObjectClass(theEnv, theObj);
		puts(""); fflush(stdout);
		printf("%p\n", cls); fflush(stdout);
		printf("Vor GetMethodID()\n", cls); fflush(stdout);
		jmethodID mid = (*theEnv)->GetStaticMethodID(theEnv, cls, "sinfo", "(Ljava/lang/String;)V");
		printf("NachGetMethodID()\n", cls); fflush(stdout);
		printf("%p\n", mid); fflush(stdout);
		(*theEnv)->CallStaticVoidMethod(theEnv, theObj, mid, (*theEnv)->NewStringUTF(theEnv, infoBuf));
#	else
		puts(infoBuf);
		fflush(stdout);
#	endif
#endif
}

Hier die Ausgabe:
0ACFDBF8
Vor GetMethodID()
NachGetMethodID()
0AD919BB

0ACFDBF8
Vor GetMethodID()
NachGetMethodID()
0AD919BB

... (Noch ein paar Mal dasselbe)

0ACFDBF8
Vor GetMethodID()
NachGetMethodID()
0AD919BB

0ACFDBF8
Vor GetMethodID()
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# Internal Error (4B4C4153530E435050005D), pid=3404, tid=3664
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode)
# An error report file with more information is saved as hs_err_pid3404.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#


Das heißt der Fehler geschieht innerhalb der GetStaticMethodID

Eine anderer Vorschlag:

Hat jemand ein funktionierendes Beispiel einer Stringübergabe an Java
von C aus.

Dann könnte ich testen, ob dieses bei mir läuft.
 

Leroy42

Top Contributor
thE_29 hat gesagt.:
Machst du eigentlich absichtlich C oder warum nimmst du nicht C++?

Absichtlich: Der zu testende Code wird später 1:1 auf einer MCU laufen, die eine Uhr steuert.

Aber auch sonst hätte ich lieber C als C++ genommen, weil mir C++ in den
letzten Jahren irgendwie fremd geworden ist (Woran das wohl liegen mag? ???:L )

Wenn du mir jedoch eine MCU zeigst, die in 32 KB Programm-
und 2 KB RAM-Speicher einen in C++ geschriebenen Code unterbringt,
überdenke ich meine Entscheidung vielleicht noch :cool:
 
G

Guest

Gast
Leroy42 hat gesagt.:
Hat jemand ein funktionierendes Beispiel einer Stringübergabe an Java
von C aus.

An der sollte es hier nicht liegen. So wie du deine Meldungen ausgibst, tritt der Fehler beim ermitteln der M.ID der statischen Methode auf:

Leroy42 hat gesagt.:
Das heißt der Fehler geschieht innerhalb der GetStaticMethodID

Sollte nur die Methode in einer Klasse nicht gefunden werden, würdest du einfach nur mid == 0 bekommen. Die exception sollte also aus einem anderen Grund auftreten. Hier stellt sich für mich die Frage, ob theEnv und cls gültig sind. Insbesondere nochmal schauen, ob du die nicht doch irgendwann veränderst!
 

Leroy42

Top Contributor
Anonymous hat gesagt.:
Die exception sollte also aus einem anderen Grund auftreten. Hier stellt sich für mich die Frage, ob theEnv und cls gültig sind. Insbesondere nochmal schauen, ob du die nicht doch irgendwann veränderst!

Sie werden am Anfang durch Aufruf einer C-Methode an den C-Teil übergeben
und dort gespeichert. Verändert werden Sie auch nicht, wie du an der von
mir geposteten Ausgabe sehen kannst:

Eclipse-Ausgabefenster hat gesagt.:
0ACFDBF8
Vor GetMethodID()
NachGetMethodID()
0AD919BB

... (Noch ein paar Mal dasselbe)

0ACFDBF8
Vor GetMethodID()
NachGetMethodID()
0AD919BB

0ACFDBF8
Vor GetMethodID()
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#

Auch funktioniert der Aufruf an den vorhergehenden Stellen auch jedesmal
problemlos, und der String wird in mein JTextField geschrieben :(
 

Murray

Top Contributor
Wird die Methode evtl. aus verschiedenen Threads heraus aufgerufen? In diesem Fall würde das JavaVm::AttachCurrentThread fehlen.
 

Leroy42

Top Contributor
Murray hat gesagt.:
Wird die Methode evtl. aus verschiedenen Threads heraus aufgerufen?

:shock:

Das hört sich interessant an. Es ist nämlich so

In Ermangelung eines C-Timers (resp. meiner Unfähigkeit einen zu schreiben)
habe ich im Java-Programm einen Thread am Werkeln, der alle 10 ms
eine C-Routine aufruft (nextTick()) die dann das C-Programm veranlaßt,
z.B. die Uhrzeit hochzuzählen und, nach Ablauf einer vollen Sekunde, diese
Zeit mittels der geposteten Methode an den Java-Teil schickt. ???:L

Was ist denn dieses JavaVm::AttachCurrentThread ?

Könntest du mal ein Beispielcode schicken oder einen Link auf :###
 

Murray

Top Contributor
In etwa so:
Code:
/* ... */

JNIEnv*  Env;
jobject  Hd;
JavaVM*  Vm;
		
/* ... */

JNIEXPORT jint JNICALL Java_package_Class_doThisN (JNIEnv *env, jobject hd) {
	Env = env;
	Hd = hd;	
	Env->GetJavaVM( &Vm);
}
	
/* ... */
	
	Vm->AttachCurrentThread( (void**)&(Env), NULL);

	Env->CallStaticVoidMethod( ....);

	Vm->DetachCurrentThread();
 

Leroy42

Top Contributor
Murray hat gesagt.:
In etwa so:
Code:
...

Ähhm, könntest du das einem Ex-C-ler etwas erklären? ???:L :oops:

Soweit ich verstehe, rufe ich bei Programmstart die Funktion doThisN einmal
auf um die Variablen Env, Hd und VM zu initialisieren (Ist das jetzt eigentlich eine
statische Funktion? Also: static native void doThisN();?

Aber wann rufe ich diese 3 Funktionen AttachCurrentThread... auf?

Sie stehen doch außerhalb jeder Funktion! :shock: ???:L

Sorry für die vielleicht dummen Fragen eines Vollblut-Javanesen! :oops: :cool:
 

Murray

Top Contributor
Leroy42 hat gesagt.:
Soweit ich verstehe, rufe ich bei Programmstart die Funktion doThisN einmal
auf um die Variablen Env, Hd und VM zu initialisieren (Ist das jetzt eigentlich eine
statische Funktion? Also: static native void doThisN();?

Stimmt, diese Funktion wird (z.B. beim Start) zur Initialisierung aufgerufen - mein Beispiel ist allerdings so nicht korrekt: die Methode ist ja so deklariert, dass sie einen jint zurückliefern muss :oops:

Statisch ist die Methode nicht; die Deklaration in der Java-Klasse würde so aussehen:
Code:
public native int doThisN();

Wäre sie in Java als
Code:
public static native int doThisN();
deklariert, dann müsste die Signatur für die Implementeriung so aussehen:
Code:
JNIEXPORT jint JNICALL Java_package_Class_doThisN (JNIEnv *env, jclass cls) //--- package und Class sind hier nur (schlecht gewaehlte) Platzhalter
(also mit jclass statt jobject als zweitem Parameter)



Leroy42 hat gesagt.:
Aber wann rufe ich diese 3 Funktionen AttachCurrentThread... auf?

Sie stehen doch außerhalb jeder Funktion! :shock: ???:L

Sorry, das war wohl zu knapp; die "/* ... */"-Kommentare sollten eigentlich andeuten, dass hier noch etwas (z.B. die restliche Methode) fehlt.

Diese Funktionen gehören dahin, wo Du jetzt schon die Java-Methode aufrufst. Also einfach vor den Block
Code:
      jmethodID mid = (*theEnv)->GetStaticMethodID(theEnv, cls, "sinfo", "(Ljava/lang/String;)V");
      printf("NachGetMethodID()\n", cls); fflush(stdout);
      printf("%p\n", mid); fflush(stdout);
      (*theEnv)->CallStaticVoidMethod(theEnv, theObj, mid, (*theEnv)->NewStringUTF(theEnv, infoBuf));
das AttachCurrentThread und dahinter das DetachCurrentThread.
 

Leroy42

Top Contributor
Dann schon mal vielen Dank im Voraus. :toll:

Ich kann das leider erst heute Abend testen.

Aber ich hatte, ehrlich gesagt, wenig Hoffnung eine Lösung zu finden.

In C-Foren hatte ich zumindest zwischen 0 und <0 Erfolg.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Hilfe bei Methode Allgemeine Java-Themen 14
Ü Methoden Arrays vergleichen - Methode Allgemeine Java-Themen 1
Simon16 compareTo Methode überschreiben Allgemeine Java-Themen 4
TheSkyRider Methode über DataInputStream "auslösen" Allgemeine Java-Themen 6
M CrudRepository save Methode mocken Allgemeine Java-Themen 6
thor_norsk toString() - Methode Allgemeine Java-Themen 6
A Clean Code: Variable vs. Methode Allgemeine Java-Themen 8
Encera Zweite Main-Methode zuschalten Allgemeine Java-Themen 18
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
I Hibernate Envers - Aufruf der Methode zum Speichern selbst ausführen oder managen? Allgemeine Java-Themen 0
N rekursion mehrfach eine Methode Öffnen Allgemeine Java-Themen 4
berserkerdq2 Wenn ich eine Methode nur jede 50ms ausführen will, wie mach ich das? Allgemeine Java-Themen 4
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
N Schnellste Methode, ein Array durchzugehen? Allgemeine Java-Themen 9
E Methoden abstract static Methode Allgemeine Java-Themen 8
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
F Getter Methode aufrufen funktioniert nicht Allgemeine Java-Themen 1
B In Java Methode mit generic input und output basteln? Allgemeine Java-Themen 4
goldmensch Datentypen Welche Methode hat die bessere Performance? Allgemeine Java-Themen 12
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
T C++ Methode Übersetzung in Java Allgemeine Java-Themen 3
L Erste Schritte TDD testen einer Methode mit injezierten Services? Allgemeine Java-Themen 12
R @author vor Methode (eclipse) Allgemeine Java-Themen 1
J RotSchwarzBaum: Löschen mittels insert-Methode Allgemeine Java-Themen 20
Y Java Bruttoberechnen + runden Methode Allgemeine Java-Themen 1
R Warum ist die Methode unendlich oft rekursiv? Allgemeine Java-Themen 5
R Methoden Was fehlt mir bzw. muss ich bei der Methode countHarshabNumbers ändern damit ich die Harshad Zahlen im Intervall [51, 79] zählen kann? Allgemeine Java-Themen 19
D ArrayListe delete Methode klappt nicht Allgemeine Java-Themen 12
Drachenbauer Wie finde ich den Aufrufer zu einer Methode, die sich nicht in meinem Projekt befindet? Allgemeine Java-Themen 2
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
Scream_ilias brute force methode verbessern? Allgemeine Java-Themen 6
Scream_ilias passwort meines pc per brute force methode knacken Allgemeine Java-Themen 4
S static methode im Interface Allgemeine Java-Themen 1
M Konstruktor einer Methode Allgemeine Java-Themen 35
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
T Sinn einer toString Methode Allgemeine Java-Themen 3
T Split() Methode funktioniert nicht?! Allgemeine Java-Themen 11
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
S Kann ich eine Methode schreiben die alle Arten von funktionalen Interfaces akzeptiert..? Allgemeine Java-Themen 21
L ToString-Methode Allgemeine Java-Themen 6
X Datentypen NPE in längerer Methode Allgemeine Java-Themen 12
I Methoden Generics-Methode Allgemeine Java-Themen 3
H Strategy Pattern - changeColor() Methode - input rgd oder hex einlesen Allgemeine Java-Themen 1
T statische Variable und nicht-statische Methode Allgemeine Java-Themen 2
B Aufruf der Methode ergibt eine Exception Allgemeine Java-Themen 13
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
F Was ist der Dateityp meines Parameters für die Main Methode. Allgemeine Java-Themen 6
F Variablen Palindromzahl (Probleme mit Methode) Allgemeine Java-Themen 9
B APi methode kurz anhalten Allgemeine Java-Themen 8
P Methode aus anderem Paket aufrufen Allgemeine Java-Themen 1
K ursprüngliche ArrayList ändert sich bei Übergabe in Methode Allgemeine Java-Themen 18
R Rekursive Methode Allgemeine Java-Themen 8
ReinerCoder Methode einer Klasse meldet Fehler "misplaced construct(s)" Allgemeine Java-Themen 13
R Wo ist mein Fehler in der Methode DRINGEND Allgemeine Java-Themen 9
I Collection - contains-Methode überschreiben (anonyme innere Klasse) Allgemeine Java-Themen 4
E RMI NULL-Pointer-Exeception wenn der RMI-Proxy eine Methode deligiert Allgemeine Java-Themen 2
S Methoden Liste soll Methode aus innerer Klasse aufrufen Allgemeine Java-Themen 4
M Methoden Generische Methode für ArrayList Allgemeine Java-Themen 7
D HTTP Aufruf einer Methode aus einem Servlet heraus Allgemeine Java-Themen 0
C Threads Methode verhält sich merkwürdig Allgemeine Java-Themen 18
R rekursive und iterative Methode Allgemeine Java-Themen 3
P Methoden Anwendung der allMatch()-Methode Allgemeine Java-Themen 5
G Programm, das nach abgearbeiteter main Methode weiterläuft Allgemeine Java-Themen 72
D Methoden Methode zum Steinschnitt Allgemeine Java-Themen 2
U OOP Warum kann ich aus meiner Methode keinen String auslesen Allgemeine Java-Themen 4
T Methoden Methode zum durchsuchen einer ArrayList Allgemeine Java-Themen 8
D Returnwert aus einer Methode gerundet ausgeben lassen Allgemeine Java-Themen 2
S equals-Methode bestimmer Klassen abfangen Allgemeine Java-Themen 2
H Methoden Methode 'updateItem' der Klasse 'TreeCell' Allgemeine Java-Themen 3
snipesss Methode greift nicht auf JTextPanel zu Allgemeine Java-Themen 3
R Methode in Methode voraussetzen Allgemeine Java-Themen 8
S Überschriebene Methode der Oberklasse der Oberklasse aufrufen. Allgemeine Java-Themen 5
D Methode dynamisch aufrufen Allgemeine Java-Themen 2
Sogomn Methode als Parameter? Allgemeine Java-Themen 3
M Eigene forEach()-Methode funktioniert nicht. Allgemeine Java-Themen 2
KaffeeFan Methoden Suche Methode um Programm kurz warten zu lassen Allgemeine Java-Themen 22
G Methoden Aus einem Event, wo ich weiß, dass es ausgeführt werden wird, eine Get-Methode basteln Allgemeine Java-Themen 8
BRoll Methode abbrechen (Invoke von außen) Allgemeine Java-Themen 5
I Methode verallgemeinern (Methode als Parameter)? Allgemeine Java-Themen 10
D generische Interface und konkrete Methode Allgemeine Java-Themen 3
G Threads Methode nebenbei ausführen, Status verarbeiten Allgemeine Java-Themen 4
H FTP Befehl/Java Methode für Submit im z/Os (Host) Allgemeine Java-Themen 1
M Fabrik Methode, gutes Beispiel? Allgemeine Java-Themen 0
M WebService - Zugriff auf Webservice Methode über Browser Allgemeine Java-Themen 1
N WaitForScript- methode in javafx Allgemeine Java-Themen 1
2 jede Stunde Methode ausführen Allgemeine Java-Themen 8
M Eine static-Methode verlassen Allgemeine Java-Themen 2
P "Overriden statische Methode" Statische Methode die vererbt wird Allgemeine Java-Themen 5
X Komponente an Methode übergeben Allgemeine Java-Themen 1
A Methode ergibt Java NullpointerException. Allgemeine Java-Themen 3
S Getestete Methode um das Beste aus URL-Nutzereingaben rauszuholen..? Allgemeine Java-Themen 4
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
D Methode mit optionalen Parametern in Interface Allgemeine Java-Themen 3
C DBConnection als Methode in mehreren Klassen Allgemeine Java-Themen 4
S Methode funktioniert nicht als ActionListener Allgemeine Java-Themen 4
M Methoden Methode Auslagern Allgemeine Java-Themen 6
P 4 Threads in einer Methode Allgemeine Java-Themen 2
A Methoden Generische Methode mit Arrays - Source Compatibility 1.7 benötigt, wieso? Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben