Поиск…


Вступление

JNI (Java Native Interface) - это мощный инструмент, который позволяет разработчикам Android использовать NDK и использовать собственный код C ++ в своих приложениях. В этом разделе описывается использование интерфейса Java <-> C ++.

Как вызвать функции в собственной библиотеке через интерфейс JNI

Интерфейс Java Native (JNI) позволяет вам вызывать собственные функции из кода Java и наоборот. В этом примере показано, как загружать и вызывать собственную функцию через JNI, она не переходит к доступу к методам и полям Java из собственного кода с использованием функций JNI .

Предположим, у вас есть родная библиотека с именем libjniexample.so в libjniexample.so project/libs/<architecture> , и вы хотите вызвать функцию из класса JNITest Java внутри пакета com.example.jniexample .

В классе JNITest объявите функцию следующим образом:

public native int testJNIfunction(int a, int b);

В вашем собственном коде определите функцию следующим образом:

#include <jni.h>

JNIEXPORT jint JNICALL Java_com_example_jniexample_JNITest_testJNIfunction(JNIEnv *pEnv, jobject thiz, jint a, jint b)
{
    return a + b;
}

Аргумент pEnv является указателем на среду JNI, которую вы можете передать функциям JNI для доступа к методам и полям объектов и классов Java. thiz указатель является jobject ссылки на объект Java , который нативный метод был вызван (или класс , если это статический метод).

В вашем Java-коде в JNITest загрузите библиотеку следующим образом:

static{
    System.loadLibrary("jniexample");
}

Обратите внимание на lib в начале, а .so в конце имени файла опущены.

Вызовите функцию native из Java следующим образом:

JNITest test = new JNITest();
int c = test.testJNIfunction(3, 4);

Как вызвать метод Java из собственного кода

Интерфейс Java Native Interface (JNI) позволяет вам вызывать функции Java из собственного кода. Вот простой пример того, как это сделать:

Код Java:

package com.example.jniexample;
public class JNITest {
    public static int getAnswer(bool) {
        return 42;
    }
}

Родной код:

int getTheAnswer()
{
    // Get JNI environment
    JNIEnv *env = JniGetEnv();

    // Find the Java class - provide package ('.' replaced to '/') and class name
    jclass jniTestClass = env->FindClass("com/example/jniexample/JNITest");

    // Find the Java method - provide parameters inside () and return value (see table below for an explanation of how to encode them) 
    jmethodID getAnswerMethod = env->GetStaticMethodID(jniTestClass, "getAnswer", "(Z)I;");

    // Calling the method
    return (int)env->CallStaticObjectMethod(jniTestClass, getAnswerMethod, (jboolean)true);
}

Подпись JNI-метода к типу Java:

Подпись JNI Тип Java
Z логический
В байт
С голец
S короткая
я ИНТ
J долго
F поплавок
D двойной
L полностью квалифицированный класс; полностью квалифицирован-класс
[ тип тип[]

Итак, для нашего примера мы использовали (Z) I - что означает, что функция получает логическое значение и возвращает int.

Утилитный метод в слое JNI

Этот метод поможет получить строку Java из строки C ++.

jstring getJavaStringFromCPPString(JNIEnv *global_env, const char* cstring) {

        jstring nullString = global_env->NewStringUTF(NULL);

        if (!cstring) {
            return nullString;
        }

        jclass strClass = global_env->FindClass("java/lang/String");
        jmethodID ctorID = global_env->GetMethodID(strClass, "<init>",
                "([BLjava/lang/String;)V");
        jstring encoding = global_env->NewStringUTF("UTF-8");

        jbyteArray bytes = global_env->NewByteArray(strlen(cstring));
        global_env->SetByteArrayRegion(bytes, 0, strlen(cstring), (jbyte*) cstring);
        jstring str = (jstring) global_env->NewObject(strClass, ctorID, bytes,
                encoding);

        global_env->DeleteLocalRef(strClass);
        global_env->DeleteLocalRef(encoding);
        global_env->DeleteLocalRef(bytes);

        return str;
    }

Этот метод поможет вам преобразовать jbyteArray в char

char* as_unsigned_char_array(JNIEnv *env, jbyteArray array) {
    jsize length = env->GetArrayLength(array);
    jbyte* buffer = new jbyte[length + 1];

    env->GetByteArrayRegion(array, 0, length, buffer);
    buffer[length] = '\0';

    return (char*) buffer;
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow