【问题标题】:Can a shared library loaded in Java call Java methods?Java中加载的共享库可以调用Java方法吗?
【发布时间】:2019-10-28 19:27:40
【问题描述】:

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

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

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

【问题讨论】:

标签: java java-native-interface shared-libraries


【解决方案1】:

你有 Adder 类和 add() 方法

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获取完整代码。

【讨论】:

    【解决方案2】:

    是的,而且通常即使 add 是私有方法。

    【讨论】:

    • 您能否举个例子或指出如何实现这一目标的正确方向?
    • 不仅如此,JNI 还可用于更改对象的其他不可变值,例如 StringInteger。这会造成各种破坏......
    猜你喜欢
    • 1970-01-01
    • 2011-08-27
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 2021-09-24
    • 2013-02-01
    相关资源
    最近更新 更多