简体   繁体   English

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

[英]Calling a Java variadic function from C through the JNI

I am currently working on creating some Java bindings for a C library I work on.我目前正在为我工作的 C 库创建一些 Java 绑定。 One of our C-structs has a char buffer that is a file system path.我们的 C 结构之一有一个字符缓冲区,它是一个文件系统路径。 After calling the C function, the buffer is correctly populated.调用 C function 后,缓冲区已正确填充。 I want to take the buffer and convert it to a java.nio.file.Path member on the Java object.我想获取缓冲区并将其转换为java.nio.file.Path上的 java.nio.file.Path 成员。

I am having some trouble however.但是我遇到了一些麻烦。 I for some reason am generating a NullPointerException within C, and I can't really see the problem.由于某种原因,我在 C 中生成了NullPointerException ,但我看不出问题所在。

The way to create a java.nio.file.Path object is going through java.nio.file.Paths::get() .创建java.nio.file.Path object 的方法是通过java.nio.file.Paths::get()

Here is the relevant C code:以下是相关的 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;

And the Java class for good measure:和 Java class 很好的措施:

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

All I can think is that somehow I am not calling the Java variadic function properly.我能想到的是,不知何故我没有正确调用 Java 可变参数 function。 I have also tried passing NULL as an extra argument to the method call, but ended up with the same issue.我还尝试将NULL作为方法调用的额外参数传递,但最终遇到了同样的问题。

The method you are trying to invoke is declared as get(String first, String... more) .您尝试调用的方法被声明为get(String first, String... more) The variadic syntax in Java is just sugar for an array of the specified type, ie the two arguments of this method are really String and String[] -- which you correctly coded in the GetStaticMethodID call as (Ljava/lang/String;[Ljava/lang/String;) . Java 中的可变参数语法只是指定类型数组的糖,即此方法的两个arguments 实际上是StringString[] - 您在GetStaticMethodID调用中正确编码为(Ljava/lang/String;[Ljava/lang/String;)

So to call it you need two arguments: one String and one String[] (array) -- and (for your case) the array must contain zero elements, but such an empty array is not the same as NULL.因此,要调用它,您需要两个arguments:一个String和一个String[] (数组) ——并且(对于您的情况)该数组必须包含零个元素,但这样的空数组与NULL不同。 Have a gander at NewObjectArray .看看NewObjectArray

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM