如何在java中保存从jni返回的void *以供以后使用

时间:2016-05-26 19:28:04

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

我正在为JNI C函数编写一个Java包装器,它返回一个"句柄" - void * - 我需要准确保存值,以便以后能够将其传递回另一个JNI函数。在C代码中,我可以将void *转换为unsigned long,但Java没有unsigned或long值。

具体来说,我试图做这样的事情:

// in C
JNIEXPORT jint JNICALL Java_com_example_jni_hooks_ll_Dlopen(JNIEnv* env,jstring j_filename,jint flag)
{
    const char* filename = (*env)->GetStringUTFChars(env,j_filename,0);
    return (int) dlopen(filename,flag);
}
JNIEXPORT jvoid JNICALL Java_com_example_jni_hooks_ll_Dlclose(JNIEnv* env,jint handle)
{
    dlclose(handle);
}

// in Java
public static native int ll_Dlopen(String filename,int flag);
public static native void ll_Dlclose(int handle);

int handle=ll_Dlopen("filename.so",0);
    .
    .
    .
ll_Dlclose(handle);

Java代码除了将其传递回JNI代码之外,不会对句柄执行任何操作。我的问题是,为此使用Java int是否安全?如果没有,应该使用哪种数据类型

N.B。 - 上面的代码是对问题的过度简化说明,而不是我正在使用的代码的准确表示。

1 个答案:

答案 0 :(得分:0)

正如@Paul的评论所示,Java的长类型是64位整数。由于指针值在Java中仅被视为不透明值,因此当Java int值被Java long替换时,我的问题中的代码是正确的:

// in C
JNIEXPORT jlong JNICALL Java_com_example_jni_hooks_ll_Dlopen(JNIEnv* env,jstring j_filename,jint flag)
{
    const char* filename = (*env)->GetStringUTFChars(env,j_filename,0);
    return (unsigned long) dlopen(filename,flag);
}
JNIEXPORT jvoid JNICALL Java_com_example_jni_hooks_ll_Dlclose(JNIEnv* env,jlong handle)
{
    dlclose((void*)(unsigned long)handle);
}

// in Java
public static native long ll_Dlopen(String filename,int flag);
public static native void ll_Dlclose(long handle);

long handle=ll_Dlopen("filename.so",0);
    .
    .
    .
ll_Dlclose(handle);