java - Java中加载的共享库可以调用Java方法吗?

标签 java java-native-interface shared-libraries

假设我有一个具有以下类的 Java 应用程序,

class Adder {
    public int add(int a, int b) { return a + b; }
}

如果我使用 System.loadLibrary("libABC.so") 将共享库(.so 文件)加载到 Java 中,libABC 中的 native 方法可以调用 adder.add(1,2) 其中 adderAdder 的实例?如果是,非常感谢一个正确方向的示例/指针。

最佳答案

您有带有 add() 方法的 Adder

class Adder {
    public int add(int a, int b) { return a + b; }
}

例如,我们在 Demo 类中有一个名为 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()调用mAdderadd()方法。

#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 - Java中加载的共享库可以调用Java方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58597233/

相关文章:

java - tomcat - HTTP 连接器 maxThreads/acceptCount 与 JDBC 池 maxActive 之间的比率

java - 什么是弱全局引用?它与全局引用有何不同?

android - 使用 ndk-build 编译时找不到 OpenCV header

matlab - 如何定位内置函数的定义位置?

java - 使用 Java 将空间元数据注入(inject)视频的方法

c# - "Double-Checked Locking is Broken"是仅限 Java 的东西吗?

java - 升级已发布的 Android App 的 minSdk

java - 线程完成时如何测试结果 - java

android - 即使应用程序已关闭,如何从服务进行 JNI 调用?

linux - 为 ARM 使用 lib 时获取 "undefined reference to",但在编译时获取 0x104567910