Может ли общая библиотека, загруженная в Java, вызывать методы Java? - PullRequest
0 голосов
/ 28 октября 2019

Допустим, у меня есть приложение Java, которое имеет следующий класс:

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

Если я загружаю в Java разделяемую библиотеку (.so файл), используя System.loadLibrary("libABC.so"), может ли собственный метод в libABC invoke adder.add(1,2), где adder является экземпляром Adder? Если да, пример / указатель в правильном направлении был бы очень признателен.

Ответы [ 2 ]

1 голос
/ 30 октября 2019

У вас есть Сумматор класс с add () метод

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

Например, у нас есть экземпляр с именем 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 () для получения mAdder из thiz .
Используйте CallIntMethod () для вызова add () метода mAdder .

#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);
}

Вы можете получить полный код на здесь .

1 голос
/ 28 октября 2019

Да, и часто, даже если add - это закрытый метод.

...