我正在为 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);
除了将句柄传递回 JNI 代码之外,Java 代码不会对句柄执行任何操作。我的问题是使用 Java int 是否安全?如果不是,我应该使用什么数据类型?
注意- 上面的代码是对问题的过度简化的说明,而不是我正在使用的代码的准确表示。
最佳答案
正如 @Paul 的评论中指出的,Java 的 long 类型是 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);
关于java - java中如何保存从jni返回的void*以供以后使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37469465/