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

标签 java c java-native-interface

我目前正在为我使用的 C 库创建一些 Java 绑定(bind)。我们的一个 C 结构有一个字符缓冲区,它是一个文件系统路径。调用 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 作为方法调用的额外参数传递,但最终遇到了同样的问题。

最佳答案

您尝试调用的方法声明为 get(String first, String... more)。 Java 中的可变参数语法只是指定类型数组的糖分,即该方法的两个 参数实际上是StringString[] -- 您在 GetStaticMethodID 调用中正确编码为 (Ljava/lang/String;[Ljava/lang/String;)

所以要调用它你需要两个参数:一个String和一个String[](数组) -- 并且(对于您的情况)数组必须包含零个元素,但这样的空数组与 NULL 相同。查看 NewObjectArray

关于java - 通过 JNI 从 C 调用 Java 可变参数函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70454689/

相关文章:

java - 带有 java.util.ArrayList 和 "Enum"的异常错误消息

java - 检查数据库中存在的大量字符串的有效方法

c++ - DLL 中的共享内存

linux - Linux 上的 JNI_CreateJavaVM 会破坏堆栈?

Android JNI - 在没有 DetachCurrentThread 的情况下调用 AttachCurrentThread

java - C++ 中的模块路径到 Java JNI 调用

java - Spring MVC中如何集成多种 View 技术

Apache Axis 2 中没有时区的 Java 日历

c - 使用 dup2 和 execv 在 C 中获取文件夹内容

c - 如何防止缓冲区溢出造成的密码屏蔽