通过JNI从C调用Java可变参数函数

3
我目前正在创建一些Java绑定,用于我正在工作的C库。我们的一个C结构有一个char缓冲区,是一个文件系统路径。调用C函数后,缓冲区会被正确填充。我想将缓冲区转换为Java对象上的java.nio.file.Path成员。
然而,我遇到了一些问题。由于某种原因,在C内部生成了NullPointerException,我无法看到问题所在。
创建java.nio.file.Path对象的方法是通过java.nio.file.Paths::get()进行的。
以下是相关的C代码:
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); // exception generated here
if ((*env)->ExceptionCheck(env))
    return;

同时附上 Java 类:

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;
    }
}

我能想到的只有我可能没有正确调用Java的可变参数函数。我还尝试在方法调用时传递NULL作为额外参数,但仍然出现了相同的问题。

你有堆栈跟踪吗?哪个语句导致了NPE?当您逐步执行代码时,您的IDE会显示什么? - Jim Garrison
Jim在通过Maven运行测试并通过gdb连接到进程的特定情况下获取堆栈跟踪方面遇到了困难。我需要继续努力解决这个问题。如果你有任何资源,那也会很有价值。与此同时,我将尝试回答所建议的方法。 - tristan957
1个回答

5

你正在尝试调用的方法声明为get(String first, String... more)。在Java中,变长语法只是特定类型的数组语法糖,也就是说,这个方法的两个参数实际上是 StringString[] -- 你在 GetStaticMethodID 调用中正确地编码为 (Ljava/lang/String;[Ljava/lang/String;)

因此,要调用它,你需要两个参数:一个是String,另一个是String[](数组),对于你的情况,这个数组必须不包含任何元素,但这样的空数组与 NULL 是不同的。请参考 NewObjectArray


哇,这绝对是解决方法。我想我之前没有明白的是,零元素数组不等同于NULL。我曾考虑过尝试它,但因为我认为需要创建一个零元素数组似乎很奇怪,所以放弃了。回想起来,我应该试一试。非常感谢你的帮助。 - tristan957
1
@tristan957 一个零元素的数组需要保护用户免受空指针异常的影响。对零元素数组进行解引用是一种无操作,但对空指针进行解引用则会导致未定义的行为异常。 - Abraham Le

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接