开发者

Java JNI and ellipsis mess

I have a f开发者_C百科unction in c that adds a row to a table. The function takes as arguments various orderings of ints, floats, and strings by using an ellipsis add_row(int arg1, int arg2, ...) and parses this information based on how the columns are set up.

I need to call this function from Java and am using JNI. I'm not sure what the best way to do this is especially with Java's stricter typing. I've considered a few solutions but none of them seem any good / I'm not sure how to implement them: passing everything as strings, passing a jobjectArray, or passing cell values one at a time.

Any help is much appreciated.

Thanks,

Ben


The Java side is simple. Define the native method as (Object...args). Then you will get autoboxing at the call sites, and in the JNI method you will get an array of Objects whose elements may be String, Integer, Double, etc, which you can check with GetObjectClass and do the appropriate thing.

However you are then going to have a major problem constructing the actual call to the method in C, and I don't know how you're going to get around that at all.


This is less a problem with Java and JNI and more a problem of how to call a var args function in C with a dynamic list of arguments. See Calling a C function with a varargs argument dynamically which suggests having two versions of the var args function (although I think the convention is more to allow passthrough of an existing va_list, rather than for constructing one (which seems to be quite involved)).

The JNI bit should be just to define a Java native method with object array arguments which will have a C equivalent receiving the array. Use the JNI API to convert the values into the C equivalents (ints and ANSI strings) then load them into the var args structure and call your vadd_row() function.

Java:

package mypackage;
public class MyClass {
    ...
    public native void addRow(Object[] args);
    ...
}

C:

void vadd_row(int arg1, int arg2, va_list argp) {
    ... your function ...
}

void add_row(int arg1, int arg2, ...) {
    va_list argp;

    va_start(argp, arg2);
    vadd_row(int arg1, int arg2, argp);
    va_end(argp);
}


JNIEXPORT void JNICALL mypackage_MyClass_addRow(JNIEnv *env, jobject this, jint arg1, jint arg2, jobjectArray jarg_array) {
    va_list argp;
    /* need to construct argp, see link below for hints[1]; go through each element
       of the java array, get the object; convert to primitive value or ANSI string,
       then encode it into the va_list */
    vadd_row((int)arg1, (int)arg2, argp);
}

[1] https://bbs.archlinux.org/viewtopic.php?pid=238721

Is it worth the hassle?

Consider just writing a simpler C function that receives the arguments in an array, then create a wrapper that uses var args if needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜