Java 中加载的共享库可以调用 Java 方法吗?
Can a shared library loaded in Java call Java methods?
假设我有一个 Java 应用程序,它具有以下 class、
class Adder {
public int add(int a, int b) { return a + b; }
}
如果我使用 System.loadLibrary("libABC.so")
加载到 Java 共享库(.so 文件),libABC
中的本机方法可以调用 adder.add(1,2)
其中 adder
是Adder
的实例化?如果是,将不胜感激 example/pointer 方向正确。
是的,通常即使 add 是私有方法。
您有 Adder class 和 add() 方法
class Adder {
public int add(int a, int b) { return a + b; }
}
例如,我们在classDemo中有一个名为mAdder的实例。
public class Demo {
native void nativeEntry();
Adder mAdder = new Adder();
public static void main(String[] args){
System.loadLibrary("JNIBridge");
Demo demo = new Demo();
demo.nativeEntry();
}
}
在 JNI 中,demo 对象存储在 thiz 指针中。
使用 GetObjectField() 从 thiz.
获取 mAdder
使用 CallIntMethod() 调用 mAdder 的 add() 方法。
#include <jni.h>
#include <stdio.h>
//use command
//javah -jni Demo
//to generate jni method declaration
JNIEXPORT void JNICALL Java_Demo_nativeEntry(JNIEnv *env, jobject thiz) {
//thiz is the calling object
//in java main(), we call: demo.nativeEntry()
//so, thiz is demo object
//get class Demo
jclass demoCls = (*env)->FindClass(env, "Demo");
//get id of mAdder in Demo
jfieldID adderField = (*env)->GetFieldID(env, demoCls, "mAdder", "LAdder;");
//get object mAdder from object demo
jobject adderObject = (*env)->GetObjectField(env, thiz, adderField);
//get class Adder
jclass adderCls = (*env)->FindClass(env, "Adder");
//get id of method add in Adder
jmethodID addMethod = (*env)->GetMethodID(env, adderCls, "add", "(II)I");
// (II)I: is signature of method Adder.add()
// use command:
//javap -s -p Adder
//to get method signature
//call method add of object mAdder
jint sum = (*env)->CallIntMethod(env, adderObject, addMethod, 10, 20);
//sum = add(10,20)
printf("sum = %d\n", sum);
}
您可以在 here 获得完整代码。
假设我有一个 Java 应用程序,它具有以下 class、
class Adder {
public int add(int a, int b) { return a + b; }
}
如果我使用 System.loadLibrary("libABC.so")
加载到 Java 共享库(.so 文件),libABC
中的本机方法可以调用 adder.add(1,2)
其中 adder
是Adder
的实例化?如果是,将不胜感激 example/pointer 方向正确。
是的,通常即使 add 是私有方法。
您有 Adder class 和 add() 方法
class Adder {
public int add(int a, int b) { return a + b; }
}
例如,我们在classDemo中有一个名为mAdder的实例。
public class Demo {
native void nativeEntry();
Adder mAdder = new Adder();
public static void main(String[] args){
System.loadLibrary("JNIBridge");
Demo demo = new Demo();
demo.nativeEntry();
}
}
在 JNI 中,demo 对象存储在 thiz 指针中。
使用 GetObjectField() 从 thiz.
获取 mAdder
使用 CallIntMethod() 调用 mAdder 的 add() 方法。
#include <jni.h>
#include <stdio.h>
//use command
//javah -jni Demo
//to generate jni method declaration
JNIEXPORT void JNICALL Java_Demo_nativeEntry(JNIEnv *env, jobject thiz) {
//thiz is the calling object
//in java main(), we call: demo.nativeEntry()
//so, thiz is demo object
//get class Demo
jclass demoCls = (*env)->FindClass(env, "Demo");
//get id of mAdder in Demo
jfieldID adderField = (*env)->GetFieldID(env, demoCls, "mAdder", "LAdder;");
//get object mAdder from object demo
jobject adderObject = (*env)->GetObjectField(env, thiz, adderField);
//get class Adder
jclass adderCls = (*env)->FindClass(env, "Adder");
//get id of method add in Adder
jmethodID addMethod = (*env)->GetMethodID(env, adderCls, "add", "(II)I");
// (II)I: is signature of method Adder.add()
// use command:
//javap -s -p Adder
//to get method signature
//call method add of object mAdder
jint sum = (*env)->CallIntMethod(env, adderObject, addMethod, 10, 20);
//sum = add(10,20)
printf("sum = %d\n", sum);
}
您可以在 here 获得完整代码。