java 层:
//成员变量
private int number = 88;
private String message = "Hello from Java";
//静态变量
private static double numberStatic = 1998.2;
//访问对象
private native void modifyVariable();
c 层:
JNIEXPORT void JNICALL Java_HelloJNI_modifyVariable(JNIEnv *env, jobject obj) {
//0.获取到 jcalss
jclass thisClass = env->GetObjectClass(obj);
//1.获取到 filed 的 ID
jfieldID numberId = env->GetFieldID(thisClass, "number", "I");
if (nullptr == numberId) {
return;
}
//2.根据 id 获取到 filed
jint number = env->GetIntField(obj, numberId);
cout << "In C++, the number from java is " << number << endl;
//3.给 filed 赋值
number = 99;
env->SetIntField(obj, numberId, number);
//获取一个 String 成员变量,与获取 number 类似
jfieldID messageId = env->GetFieldID(thisClass, "message", "Ljava/lang/String;");
if(NULL == messageId) return;
jstring message = (jstring)env->GetObjectField(obj, messageId);
const char* str = env->GetStringUTFChars(message, NULL);
if(NULL == str) return;
cout << "In C++, the message is " << str << endl;
//内存清理
env->ReleaseStringUTFChars(message, str);
message = env->NewStringUTF("Hello from C++");
if(NULL == message) return;
env->SetObjectField(obj, messageId, message);
//访问静态变量
jfieldID staticNumberId = env->GetStaticFieldID(thisClass, "numberStatic", "D");
if (nullptr == staticNumberId) {
return;
}
jdouble number2 = env->GetStaticDoubleField(thisClass, staticNumberId);
cout << "In C++, the static double is " << number2 << endl;
number2 = 77.88;
env->SetStaticDoubleField(thisClass, fidStaticNumber, number2);
}
GetFieldID 的最后一个参数是字段描述符:
描述符 | 含义 |
---|---|
I | int |
B | byte |
S | short |
J | long |
F | float |
D | double |
C | char |
Z | boolean |
[I | int[] |
Ljava/lang/String | String |
[Ljava/lang/String | String[] |
java 层:
public class TestJNICallBackMethod{
static {
System.loadLibrary("myjni");
}
private native void nativeMethod();
private void callback(){
System.out.println("In Java");
}
private void callback(String message){
System.out.println("In Java with " + message);
}
private double callbackAverage(int n1, int n2){
return ((double)n1 + n2) / 2.0;
}
private static String callbackStatic(){
return "From static Java method";
}
public static void main(String[] args){
new TestJNICallBackMethod().nativeMethod();
}
}
cpp 层:
#include "TestJNICallBackMethod.h"
#include <iostream>
using namespace std;
JNIEXPORT void JNICALL Java_TestJNICallBackMethod_nativeMethod(
JNIEnv *env, jobject thisObj)
{
jclass thisClass = env->GetObjectClass(thisObj);
jmethodID midCallBack = env->GetMethodID(thisClass, "callback", "()V");
if(NULL == midCallBack) return;
cout << "In C++, call back Java's callback()\n";
// Call back the method (which returns void), based on the Method ID
env->CallVoidMethod(thisObj, midCallBack);
jmethodID midCallBackStr = env->GetMethodID(thisClass, "callback", "(Ljava/lang/String;)V");
if(NULL == midCallBackStr) return;
cout << "In C++, call back Java's callback(String)\n";
jstring message = env->NewStringUTF("Hello from C++");
env->CallVoidMethod(thisObj, midCallBackStr, message);
jmethodID midCallBackAverage = env->GetMethodID(thisClass, "callbackAverage", "(II)D");
if(NULL == midCallBackAverage) return;
jdouble average = env->CallDoubleMethod(thisObj, midCallBackAverage, 2, 3);
cout << "In C++, the average is " << average << endl;
jmethodID midCallBackStatic = env->GetStaticMethodID(thisClass, "callbackStatic", "()Ljava/lang/String;");
if(NULL == midCallBackStatic) return;
jstring resultJNIStr = (jstring)env->CallStaticObjectMethod(thisClass, midCallBackStatic);
const char* resultStr = env->GetStringUTFChars(resultJNIStr, NULL);
if(NULL == resultStr) return;
cout << "In C++, the returned string is " << resultStr << endl;
env->ReleaseStringUTFChars(resultJNIStr, resultStr);
}