es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Llamando a una función variádica de Java desde C a través de JNI.

Actualmente estoy trabajando en la creación de enlaces Java para una biblioteca C en la que trabajo. Una de nuestras estructuras C tiene un búfer de caracteres que es una ruta del sistema de archivos. Después de llamar a la función C, el búfer se completa correctamente. Quiero tomar el búfer y convertirlo en un miembro java.nio.file.Path en el objeto Java.

Sin embargo, tengo algunos problemas. Por alguna razón, estoy generando una NullPointerException dentro de C y no puedo ver realmente el problema.

La forma de crear un objeto java.nio.file.Path es a través de java.nio.file.Paths::get().

Aquí está el código C relevante:

const jclass paths_class = (*env)->FindClass(env, "java/nio/file/Paths");
if ((*env)->ExceptionCheck(env))
    return;
const jmethodID get_method = (*env)->GetStaticMethodID(
    env, paths_class, "get", "(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;");
if ((*env)->ExceptionCheck(env))
    return;
const jstring path_str = (*env)->NewStringUTF(env, info.mi_path);
if ((*env)->ExceptionCheck(env))
    return;
const jobject path_obj =
   (*env)->CallStaticObjectMethod(env, paths_class, get_method, path_str); // excepción generada aquí
if ((*env)->ExceptionCheck(env))
    return;

Y la clase Java para mayor claridad:

public final class MclassInfo {
    private native void _get(final Kvdb kvdb, Mclass mclass) throws HseException;

    private long allocatedBytes;
    private long usedBytes;
    private Path path;

    MclassInfo(final Kvdb kvdb, final Mclass mclass) throws HseException {
        _get(kvdb, mclass);
    }

    public long getAllocatedBytes() {
        return allocatedBytes;
    }

    public long getUsedBytes() {
        return usedBytes;
    }

    public Path getPath() {
        return path;
    }
}

Lo único que puedo pensar es que de alguna manera no estoy llamando correctamente a la función variádica de Java. También he intentado pasar NULL como un argumento adicional a la llamada del método, pero terminé con el mismo problema.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución

    La NullPointerException probablemente se genera porque el método java.nio.file.Paths.get() espera un array de cadenas como segundo argumento, pero no se está proporcionando. En el código C, cambie la línea que crea la variable jstring path_str por la siguiente:

    const jstring path_str = (*env)->NewStringUTF(env, info.mi_path);
    

    Luego, cree un array vacío de cadenas y páselo como segundo argumento al método get(). Aquí está el código C actualizado:

    const jclass paths_class = (*env)->FindClass(env, "java/nio/file/Paths");
    if ((*env)->ExceptionCheck(env))
        return;
    const jmethodID get_method = (*env)->GetStaticMethodID(
        env, paths_class, "get", "(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;");
    if ((*env)->ExceptionCheck(env))
        return;
    const jstring path_str = (*env)->NewStringUTF(env, info.mi_path);
    if ((*env)->ExceptionCheck(env))
        return;
    const jobjectArray empty_arr = (*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), NULL);
    if ((*env)->ExceptionCheck(env))
        return;
    const jobject path_obj =
        (*env)->CallStaticObjectMethod(env, paths_class, get_method, path_str, empty_arr); // no se generan excepciones aquí
    if ((*env)->ExceptionCheck(env))
        return;
    

    Esto debería solucionar el NullPointerException y poblar correctamente el miembro path del objeto Java MclassInfo.

Comments are closed.