Können wir mit JNI benutzerdefinierte Datentypen von Java an C (oder umgekehrt) übergeben? Ich sehe eine Zuordnung von primitiven Datentypen zu Typen in C, bin mir aber nicht sicher, ob wir unsere eigenen Datentypen übertragen können (z. B. ein Mitarbeiterobjekt senden oder zurückgeben oder so!).
Übergeben von Datentypen von Java an C (oder umgekehrt) mit JNI
Eintopf
Wenn Sie dies mit vielen Objekten tun, wäre etwas wie Swig am besten. Sie könnten den Jobject-Typ verwenden, um benutzerdefinierte Objekte zu übergeben. Die Syntax ist nicht schön, vielleicht gibt es einen besseren Weg, dies zu schreiben.
Beispiel Mitarbeiterobjekt:
public class Employee {
private int age;
public Employee(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
Rufen Sie diesen Code von einem Client aus auf:
public class Client {
public Client() {
Employee emp = new Employee(32);
System.out.println("Pass employee to C and get age back: "+getAgeC(emp));
Employee emp2 = createWithAge(23);
System.out.println("Get employee object from C: "+emp2.getAge());
}
public native int getAgeC(Employee emp);
public native Employee createWithAge(int age);
}
Sie könnten JNI-Funktionen wie diese haben, um ein Mitarbeiterobjekt von Java an C als Argument der Jobject-Methode zu übergeben:
JNIEXPORT jint JNICALL Java_Client_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) {
jclass employeeClass = (*env)->GetObjectClass(env, employeeObject);
jmethodID midGetAge = (*env)->GetMethodID(env, employeeClass, "getAge", "()I");
int age = (*env)->CallIntMethod(env, employeeObject, midGetAge);
return age;
}
Wenn Sie ein Mitarbeiterobjekt als Jobobjekt von C an Java zurückgeben, könnten Sie Folgendes verwenden:
JNIEXPORT jobject JNICALL Java_Client_createWithAge(JNIEnv *env, jobject callingObject, jint age) {
jclass employeeClass = (*env)->FindClass(env,"LEmployee;");
jmethodID midConstructor = (*env)->GetMethodID(env, employeeClass, "<init>", "(I)V");
jobject employeeObject = (*env)->NewObject(env, employeeClass, midConstructor, age);
return employeeObject;
}
-
Ich habe Probleme mit “LEmployee;” Teil, den ich mit “com.pak1.Employee” und mit “Lcom.pak.Employee” ausprobiert habe; aber kein Ergebnis, irgendwelche Ideen?
– Lukas
9. Oktober 2013 um 10:27 Uhr
-
@Lukap: Wenn Ihre Klasse com.pak.Employee ist, lautet die Signatur der Klasse “Lcom/pak/Employee”.
– nautilusvn
6. Juli 2014 um 10:26 Uhr
-
@mafioso können Sie ein Objekt der Klasse “Ljava/lang/string;” erstellen. Kommentieren Sie der Vollständigkeit halber, bezweifeln Sie, dass Sie das tatsächlich noch brauchen …
– Nefo
3. November 2017 um 12:27 Uhr
-
Das
jclass proc_jclass = env->FindClass(“Lcom/my/class/JavaClass”);
-Methode muss in der ERSTEN ZEILE Ihrer aufgerufen werdenJNI
funktionieren, sonst können Sie feststellenClassNotFoundExceptions
. Auch das hat bei mir mit dem Semikolon im Klassenpfad nicht funktioniert. Nachdem ich das Semikolon aus der Klassenpfadzeichenfolge entfernt hatte, funktionierte es. Dies ist eine großartige Antwort!– Sakiboy
28. Januar 2019 um 20:24 Uhr
-
swig ist zu komplex und schwer zu bedienen.
– Yugi
17. Mai 2021 um 15:54 Uhr
Du kannst. Wenn Sie die Java/C-Übersetzung vereinfachen möchten, schauen Sie sich das an Schluckmit dem Sie übersetzen können zwischen Java- und C/C++-Strukturen auf geradlinige Weise..
– Brian Agnew
23. März 2010 um 23:26 Uhr
Sie können verwenden JNA Strukturen einfach herumreichen. Mit JNA können Sie Ihre Bindung vollständig in Java-Code schreiben. 🙂
– C. K. Young
23. März 2010 um 23:52 Uhr
baeldung.com/…
– Leponzo
5. Juli 2021 um 18:41 Uhr