Сконфигурируйте SWIG для создания соответствующего типа данных Java для функции C с выходным параметром int32_t - PullRequest
1 голос
/ 01 декабря 2011

У меня проблемы с передачей соответствующего типа данных Java для параметра длины функции fetchByType C из моей реализации Java (обе ниже). На стороне C параметр * length - это указатель на переменную длины (выходной), указывающий размер данных, возвращаемых из функции fetchByType C. Я попытался использовать SWIG% apply int32_t {int32_t *} и передать int, инициализированный в 0, из моей реализации Java, но это не удалось. Я также попытался передать SWIGTYPE_p_int, как показано ниже, но это также не работает. К сожалению, у меня нет исключений, так как это просто сбой.

C Функция:

void * fetchByType(struct row_t *result_row, type_t attribute, int32_t *length);

Сгенерированный Java из SWIG:

public static String fetchByType(SWIGTYPE_p_result_row_t result_row, type_t attribute, SWIGTYPE_p_int length)

Реализация Java:

SWIGTYPE_p_int length = new SWIGTYPE_p_int();
fetchByType(result_row, attribute, length)

1 Ответ

3 голосов
/ 01 декабря 2011

Проблема здесь в том, что вам нужно передать что-то, что можно изменить в функцию C. Это означает, что вы не можете использовать примитив в Java (например, int), поскольку Java всегда передает примитивы по значению.

Есть только один разумный способ обойти это. На самом деле SWIG уже предоставляет несколько типов карт, которые мы можем использовать для передачи этого в виде массива. Массивы в Java являются «объектами», поэтому int[] передается по ссылке, хотя int не передается. Упрощенный пример, основанный на показанной выше функции, первый test.h:

inline void fetchByType(int32_t *length) {
  *length = 123;
}

И файл модуля, test.i:

%module test

%{
#include "test.h"
%}

// knows about things like int *OUTPUT:
%include "typemaps.i"
// knows about int32_t
%include "stdint.i"
// let's have an int32_t *OUTPUT for our int32_t *lenght
%apply int32_t *OUTPUT { int32_t *length }

%include "test.h"

Это просто гарантирует, что мы применяем соответствующую *OUTPUT карту типов. (stdint.i отображает это на настоящий примитив C для вас). Я проверил с:

public class run {
  public static void main(String[] argv) {
    int arr[] = new int[1];
    test.fetchByType(arr);
    System.out.println(arr[0]);
  }
}

Это что-то вроде хака 1 , но его можно использовать. Другой подход может заключаться в использовании java.lang.Integer, который также представляет int и является правильным Object, поэтому передается по ссылке. Проблема в том, что java.lange.Integer является неизменным , однако, и я не совсем уверен, как это работает на стороне JNI, чтобы привести пример этого.

1 Другие языки SWIG поддерживает изменение типа возвращаемого значения для некоторых типов карт и возврат кортежа или аналогичного для аргументов OUTPUT, но на самом деле это невозможно в Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...