从JNI调用Java方法

时间:2014-02-20 11:46:02

标签: java android c android-ndk java-native-interface

在某些C库中存在具有签名的函数:int someFunction(int a);

我需要从这个函数(从本机代码)调用Java方法,以免破坏接口。 例如:

int someFunction(int a) {
    ...
    jbyteArray result = (jbyteArray)(*jEnv)->CallStaticObjectMethod(jEnv, clazz, methodId);
    ...
}

不能JNIEnv所需的someFunction中添加JNI之类的额外参数,所以我声明全局变量和函数进行初始化:

jmethodID globalMethodId;
jclass globalClass;
JavaVM* globalJVM;

void initJNI(JNIEnv * env, jclass clazz) {
    globalClass = (*env)->NewGlobalRef(env, clazz);
    (*env)->GetJavaVM(env, &globalJVM);

    globalMethodId = (*env)->GetStaticMethodID(env, clazz, "javaMethodName", "()[B");
}

JNIEnv * GetJniEnv() {
    JNIEnv * env;
    if((*globalJVM)->AttachCurrentThread(globalJVM, &env, NULL) != JNI_OK) {
        env = NULL;
    }
    return env;
}

和我的someFunction函数如下

int someFunction(int a) {
    JNIEnv * jEnv = GetJniEnv();
    jbyteArray result = (jbyteArray)(*jEnv)->CallStaticObjectMethod(jEnv, globalClass, globalMethodId);
    ...
}

这个新库的用户必须调用initJNI函数,然后调用someFunction。

这不是容易出错的方式吗?多线程怎么样?是否有更好的解决方案。

0 个答案:

没有答案