Übergeben Sie dabei die Parameter per Referenz von c++ zu java über jni
Ich bin versucht, übergeben Sie eine variable von c++ zu java-pro Referenz, die über JNI. Für den Anfang hab ich versucht, es mit einigen einfachen code:
Java
public static void inc(int val) {
System.out.println("inc called: " + val);
val++;
}
public static void dec(int val) {
System.out.println("dec called: " + val);
val--;
}
Diese sollte einfach in-/Dekrementieren einer Variablen erstellt, die in c++ - code mit einem Java-Methode.
Der c++ - Teil sieht wie folgt aus:
C++
jmethodID jDec = env->GetStaticMethodID(cls, "dec", "(I)V");
jmethodID jInc = env->GetStaticMethodID(cls, "inc", "(I)V");
jint val = 10;
printf("%d\n", val);
env->CallStaticVoidMethod(cls, jDec, &val);
printf("%d\n", val);
env->CallStaticVoidMethod(cls, jInc, val);
printf("%d\n", val);
Wie Sie sehen, ich habe versucht, sowohl per Referenz und per Wert.
Ausgabe
10
dec called: -401031272
10
inc called: 10
10
Innerhalb der c++ - code, der Wert ist die ganze Zeit 10, in Java ist es entweder die Adresse oder der Wert.
Wäre schön, wenn könnten Sie mir einen Tipp geben, vielen Dank im Voraus.
- Dieser code muss nicht einmal Sinn machen nur als reines C++. Dies ist nicht, wie die Funktionen arbeiten.
- Dieser code muss nicht einmal Sinn machen nur als Reine Java. Dies ist nicht, wie die Parameter arbeiten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie Wojtek schon sagte, Java Argumente von Wert. Sie können eine Rückgabewert Ihrer Java-code:
dann rufen Sie es von C++:
Ein weiterer Ansatz ist die Verwendung eines wrapper-Klasse statt:
sowie die folgende Java-Methode:
Können Sie dann rufen Sie diese aus Ihrem C++ - code:
Alternativ könnte man einen int[] statt der wrapper-Klasse wie vorgeschlagen von Wojtek.
"Das sollte einfach in-/Dekrementieren einer Variablen erstellt, die in c++ - code mit einem Java-Methode." Nein, es sollte nicht sein. Java übergibt Argumente von Wert, so sind Sie Inkrementieren und Dekrementieren nicht die C++ - variable, aber die variable
val
lokalen Funktioneninc
unddec
.Zunächst die folgenden nicht sinnvoll sein, selbst in einem reinen C++ - Kontext:
&val
gibt die Adresse der lokalen variableval
. Das ist in der Regel nicht selbst kompilieren in C++. Versuchen Sie es selbst:Der Grund, warum es kompiliert hier ist
CallStaticVoidMethod
wird eine Variable Funktion. Es wird erklärt wie diese:Den
...
Teil am Ende bedeutet "alles geht, aber Sie sind dafür verantwortlich, wenn Sie passieren, was ich nicht bewältigen kann, richtig zu laufen-Zeit".Dieser Ansatz ist offensichtlich zum scheitern verurteilt.
Das eigentliche problem jedoch ist die Tatsache, dass Java keine Referenzen im C++ - Sinn. Alles ist durch Wert übergeben; es gibt kein äquivalent zu einem C++
int &
parameter.Aber Java hat Zeiger, auch wenn es meist nennt, verwirrend, "Verweise". Ein Java -
Integer
Referenz, zum Beispiel, wäre einInteger *
in C++ (angenommen, dass die Existenz einerInteger
Klasse in C++). Naiv, könnte man einfach ändern Sie Ihre Methoden-Signaturen zu nehmenInteger
Argumente und hantieren mit den Gegenständen, die auf der C++ Seite, aber das wird nicht funktionieren, weil JavaInteger
- Klasse ist unveränderlich, so kann man nicht Anhängen.So was kann man wirklich tun?
Sie nutzen könnten 1-element-arrays, aber dies ist nicht eine sehr schöne Lösung; es erhöht die Menge der Fehlerüberprüfung Sie zu tun haben. Um Ihren code, der robust genug ist, würden Sie haben, um sicherzustellen, dass die arrays nicht enthalten 0 oder > 1 Elemente. Darüber hinaus arrays verwechselt wird jeder, der versteht den code.
Ist eine alternative Lösung erstellen Sie Ihre eigenen mutable integer-Klasse und verwenden. So etwas wie dieses:
(...)
Der C++ - Seite wird der code komplizierter als ein Ergebnis davon. Sie müssen zuerst suchen Sie Ihre Klasse, finden, und Ihr Konstruktor aufgerufen, zu finden und rufen Sie die
increment
Methode, die dann endlich finden, und rufen Sie dieget
Methode. Idealerweise wickeln Sie alle in einem kleinen C++ - Funktion:(Ich habe dies geschrieben aus der Spitze von meinem Kopf, so dass es möglicherweise Fehler enthalten, und Sie sollte natürlich noch eine Menge Fehlerbehandlung und möglicherweise einige
jmethodID
Optimierungen im code.)Ist dies der Mühe Wert? Wahrscheinlich nicht. Es kann gerechtfertigt sein, wenn die Java-Methoden werden auch als von vielen anderen Java-code und Sie wollen zu halten, eine einheitliche Schnittstelle. Wenn die Java-Methoden werden nur aufgerufen, aus C++ - code, dann ist das ganze Konzept ist Unsinn, und die richtige Lösung wäre dann, die Methoden geändert, um stattdessen Rückkehr der erhöhte Wert: