수색…


소개

JNI (Java Native Interface)는 Android 개발자가 NDK를 활용하고 C ++ 기본 코드를 응용 프로그램에서 사용할 수있게 해주는 강력한 도구입니다. 이 주제에서는 Java <-> C ++ 인터페이스의 사용}에 대해 설명합니다.

JNI 인터페이스를 통해 네이티브 라이브러리에서 함수를 호출하는 방법

Java Native Interface (JNI)를 사용하면 Java 코드에서 원시 함수를 호출 할 수 있으며 그 반대로도 가능합니다. 이 예는 JNI를 통해 네이티브 함수를로드하고 호출하는 방법을 보여줍니다. JNI 함수를 사용하여 원시 코드의 Java 메소드 및 필드에 액세스하지 않습니다.

project/libs/<architecture> 폴더에 libjniexample.so 라는 네이티브 라이브러리가 있고 com.example.jniexample 패키지의 JNITest Java 클래스에서 함수를 호출하려고한다고 가정합니다.

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 인수는 Java 객체 및 클래스의 메서드 및 필드에 액세스하기 위해 JNI 함수 에 전달할 수있는 JNI 환경에 대한 포인터입니다. thiz 포인터는 네이티브 메소드가 호출 된 Java 객체 (또는 정적 메소드의 경우 클래스)에 대한 jobject 참조입니다.

Java 코드에서 JNITest 에서 다음과 같이 라이브러리를로드하십시오.

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

처음에는 lib 를 사용하고 파일 이름 끝에 .so 는 생략됩니다.

다음과 같이 Java에서 원시 함수를 호출하십시오.

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

네이티브 코드에서 Java 메소드를 호출하는 방법

Java Native Interface (JNI)를 사용하면 원시 코드에서 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 메소드 서명 :

JNI 서명 Java 유형
부울
바이트
기음
에스 짧은
나는 int
일본
에프 흙손
더블
L 완전 자격 클래스; 정규화 된 클래스
[유형 유형[]

그래서 우리 예제에서는 (Z) I를 사용했습니다. 이것은 함수가 부울을 가져오고 int를 반환한다는 것을 의미합니다.

JNI 레이어의 유틸리티 메소드

이 메서드는 C ++ 문자열에서 Java 문자열을 가져 오는 데 도움이됩니다.

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