Java JNI и беспорядок с многоточием

У меня есть функция в c, которая добавляет строку в таблицу. Функция принимает в качестве аргументов различные порядки целых чисел, чисел с плавающей запятой и строк с использованием многоточия add_row(int arg1, int arg2, ...) и анализирует эту информацию в зависимости от того, как настроены столбцы.

Мне нужно вызвать эту функцию из Java, и я использую JNI. Я не уверен, как лучше всего это сделать, особенно с более строгой типизацией Java. Я рассмотрел несколько решений, но ни одно из них не кажется хорошим / я не уверен, как их реализовать: передать все в виде строк, передать jobjectArray или передать значения ячеек по одному.

Любая помощь горячо приветствуется.

Спасибо,

Бен


person Ben    schedule 01.07.2011    source источник


Ответы (2)


Это не столько проблема с Java и JNI, сколько проблема вызова функции var args в C с динамическим списком аргументов. См. Динамический вызов функции C с аргументом varargs, который предлагает наличие двух версий функции var args (хотя я думаю, что соглашение заключается скорее в том, чтобы разрешить передачу существующего va_list, а не для его создания (что кажется довольно сложным)).

Бит JNI должен быть просто для определения собственного метода Java с аргументами массива объектов, который будет иметь эквивалент C, получающий массив. Используйте API JNI для преобразования значений в эквиваленты C (целые числа и строки ANSI), затем загрузите их в структуру var args и вызовите функцию vadd_row().

Джава:

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

Стоит ли заморачиваться?

Попробуйте просто написать более простую функцию C, которая получает аргументы в виде массива, а затем создайте оболочку, которая при необходимости использует var args.

person Mike Tunnicliffe    schedule 05.08.2011

Сторона Java проста. Определите собственный метод как (Object...args). Затем вы получите автоупаковку на сайтах вызовов, а в методе JNI вы получите массив объектов, элементами которого могут быть String, Integer, Double и т. д., которые вы можете проверить с помощью GetObjectClass и сделать соответствующую вещь.

Однако тогда у вас возникнет серьезная проблема с построением фактического вызова метода на C, и я не знаю, как вы вообще собираетесь это обойти.

person user207421    schedule 01.07.2011