AndroidStudio jni C++ と Java が相互に呼び出します

1. Java が C++ を呼び出す

C++ がネイティブ メソッドを登録した後、対応する C++ ライブラリを Java クラスにロードすることを忘れないでください。

static { System.loadLibrary(“ネイティブライブラリ”); }

1. ネイティブ関数を静的に登録する

Java クラスでネイティブ メソッドを宣言すると、AndroidStudio はそのメソッドが未定義であることを通知し、その上にマウスを置くと、生成された JNI 関数が表示されます。
ここに画像の説明を挿入

クリックすると、native-lib.cpp に対応するネイティブ メソッドが自動的に生成され、それをメソッドに実装するだけです。
ここに画像の説明を挿入

2. 動的登録

また、Java クラスでネイティブ メソッドを宣言します。
宣言後、native-lib.cpp にメソッドを自分で実装します。

extern "C" JNICALL void TestJni(){
    
    

}

実装後にメソッドを登録します。

static JNINativeMethod getMethods[] = {
    
    
        {
    
    "nativeTestJni","()V",(void*)TestJni},
        {
    
    "nativeGetOffer","()Ljava/lang/String;", reinterpret_cast<void*>(getOffer)},

};

static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* getMethods,int methodsNum){
    
    
    jclass clazz;
    //找到声明native方法的类
    clazz = env->FindClass(className);
    if(clazz == NULL){
    
    
        return JNI_FALSE;
    }
    //注册函数 参数:java类 所要注册的函数数组 注册函数的个数
    if(env->RegisterNatives(clazz,getMethods,methodsNum) < 0){
    
    
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

extern "C" jint JNIEXPORT
JNICALL JNI_OnLoad(JavaVM* jvm, void* reserved) {
    
    
    JNIEnv* env = NULL;
    if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
    
    
        return -1;
    }
    assert(env != NULL);
    //注册函数 registerNatives ->registerNativeMethods ->env->RegisterNatives
    const char* className  = "com/begoit/testjni/MainActivity";
    if(!registerNativeMethods(env,className,getMethods, sizeof(getMethods)/ sizeof(getMethods[0])))
        return -1;
    //返回jni 的版本
    return JNI_VERSION_1_6;
}

注:
1. JNINativeMethod の最初のパラメータは、登録するネイティブ メソッドの名前であり、Java クラスで定義されたメソッド名と一致している必要があります。
2. JNINativeMethod の 2 番目のパラメータは、ネイティブ メソッドのパラメータと戻り値です。括弧内のパラメータはパラメータ、括弧の外は戻り値です。複数のパラメータを指定できます。Java タイプに対応するシグネチャ
ava タイプ タイプ シグネチャ

Java タイプ 型署名
ブール値 Z
バイト B
文字 C
短い S
整数
長さ J
浮く F
ダブル D
親切 L 完全修飾名。String など。その署名は Ljava/lang/util/String です。
配列 [タイプ署名、[B

3. className は登録する Java クラスです。形式に注意してください。

2. C++ が Java を呼び出す

extern "C"
JNIEXPORT void JNICALL
Java_com_begoit_xiurtcserver_XiuRTCService_OnProcessCameraData(JNIEnv *env, jobject thiz) {
    
    
    // TODO: implement OnProcessData()
    jclass myClass = env->FindClass("com/begoit/xiurtcserver/CameraProcessor");
    if (myClass == nullptr) {
    
    
        LOGE("can not find CameraProcessor class");
        return;
    }
    LOGI("find CameraProcessor class");
    
	method = env->GetMethodID(myClass, "TestJni", "()V");
    LOGI("find GetMethodID TestJni");

    jclass xiurtc = env->GetObjectClass(thiz);
    LOGI("GetObjectClass XiuRTCService");
    
    jfieldID fid = env->GetFieldID(xiurtc, "cameraProcessor",
                                   "Lcom/begoit/xiurtcserver/CameraProcessor;");
    LOGI("GetFieldID cameraProcessor");
    
    jobject camera = env->GetObjectField(thiz, fid);
    LOGI("GetObjectField cameraProcessor");

    env->CallVoidMethod(camera, method);
    LOGI("CallVoidMethod");
}

説明:
1. XiuRTCService クラスに CameraProcessor 型の CameraProcessor があり、
CameraProcessor には関数 TestJni があります。
2. XiuRTCService クラスで定義されたネイティブ メソッド OnProcessCameraData。

上記の関数は、XiuRTCService の CameraProcessor オブジェクトの TestJni メソッドを呼び出すように実装できます。

おすすめ

転載: blog.csdn.net/qq_36383272/article/details/126369969