Проблема здесь в том, что вам нужно передать что-то, что можно изменить в функцию 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.