NDK学习 之 Java对象映射C++对象

背景

我们都知道Java内存模型和C++内存模型不同,而且是分开存储和管理的。做NDK开发的小伙伴经常遇到这样一个问题:在Java层new一个对象,这个对象无法直接操作C++对象的内容。本文章就是为了解决这个问题。

解决方案

我这里想到两种方法可以实现Java对象和C++对象进行一一映射。
方案一:Java调用JNI方法new一个C++对象指针,并把指针转成long类型返回给Java
JNI代码如下:

jlong CreateGLThreadHandle(JNIEnv *env, jobject thiz) {
    GLRender *glRender = new GLRender();
    if (GL_RENDER_JNI_DEBUG) {
        DFLOGI(GL_RENDER_JNI_TAG, "CreateGLThreadHandle() handle = %ld", (long) glRender);
    }
    return (long) glRender;
}

Java代码如下,(这里使用Kotlin,原理一样)

class NativeGLRenderProxy {
    private var nativeGLRenderHandle: Long = INIT_HANDLE

    fun setNativeGLRenderHandle(nativeGLRenderHandle: Long) {
        if (INIT_HANDLE == nativeGLRenderHandle) {
            throw RuntimeException("Native GLRender handle is InValid")
        }
        this.nativeGLRenderHandle = nativeGLRenderHandle
    }
}

在返回C++对象指针时,NativeGLRenderProxy对象调用setNativeGLRenderHandle将Long类型指针对象nativeGLRenderHandle保存对象内部

fun createGLRenderHandle(): NativeGLRenderProxy {
    val nativeGLRenderProxy = NativeGLRenderProxy()
    val nativeGLRenderHandle = nativeCreateGLRenderHandle()
    nativeGLRenderProxy.setNativeGLRenderHandle(nativeGLRenderHandle)
    return nativeGLRenderProxy
}

方案二: 在JNI方法new C++对象后是将C++对象类似Java反射的方式设置给Java对象,这样JNI方法就必须有一个jmethodID对象

//对应com/yj/player/render/NativeGLRenderProxy类的setNativeGLRenderHandle方法
jmethodID setNativeGLRenderHandle;

//注册JNI方法
static jint registerNativeGLRenderMethods(JNIEnv *env) {
     jclass clazz = env->FindClass("com/yj/player/render/NativeGLRenderProxy");
    if (clazz == nullptr) {
        return JNI_ERR;
    }
    if (env->GetMethodID(clazz, "setNativeGLRenderHandle","(J)V")) {
        return JNI_ERR;
    }
    return JNI_OK;
}

//在JNI方法中callback回调到Java对象的方法中
void CreateGLThreadHandle(JNIEnv *env, jobject thiz) {
    GLRender *glRender = new GLRender();
    if (GL_RENDER_JNI_DEBUG) {
        DFLOGI(GL_RENDER_JNI_TAG, "CreateGLThreadHandle() handle = %ld", (long) glRender);
    }
    env->CallVoidMethod(thiz, setNativeGLRenderHandle, (long)glRender);
}

你可能感兴趣的:(NDK学习 之 Java对象映射C++对象)