Как сохранить void * возвращено из jni в java для последующего использования

Я пишу Java-оболочку для функции JNI C, которая возвращает «дескриптор» — 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 ответ

  1. Как указано в комментарии @Paul, тип long 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);