I już ułożyła następujący plik nagłówka, aby wykazać problem:
typedef struct { } obj_t;
const short *get_data(const obj_t *obj, int *data_len) {
(void)obj;
static short arr[] = {1,2,3,4,5};
*data_len = sizeof(arr)/sizeof(*arr);
return arr;
}
Pogadamy za pośrednictwem pliku modułu pisałem, zaczyna dość standardowy:
%module test
%{
#include "test.h"
%}
Następnie przygotowaliśmy typografię dla argumentu data_len
. Nie musi być widoczna po stronie Java, ponieważ długość będzie znana przez tablicę, ale musimy ustawić trochę miejsca na wskazanie wskaźnika i upewniamy się, że trwa on wystarczająco długo, abyśmy mogli go przeczytać później przy zwracaniu tablicy do Javy.
%typemap(in,numinputs=0,noblock=1) int *data_len {
int temp_len;
$1 = &temp_len;
}
Następnie chcemy SWIG używać short[]
na stronie Java dla Zwraca typ:
%typemap(jstype) const short *get_data "short[]"
%typemap(jtype) const short *get_data "short[]"
i jshortArray
w boku JNI - nie ma potrzeby, aby skonstruować typ serwera proxy, więc po prostu przejść zwracana wartość prosto przez:
%typemap(jni) const short *get_data "jshortArray"
%typemap(javaout) const short *get_data {
return $jnicall;
}
końcu tworzymy typemap że zamierza utworzyć nową tablicę o wielkości na podstawie długości wrócił z zabawy ction i skopiuj zwracany wynik do tablicy Java dla nas. W razie potrzeby powinniśmy tutaj uzyskać rzeczywistą tablicę wyników, ale w moim przykładzie została ona przydzielona statycznie, więc nie trzeba jej było zwalniać.
%typemap(out) const short *get_data {
$result = JCALL1(NewShortArray, jenv, temp_len);
JCALL4(SetShortArrayRegion, jenv, $result, 0, temp_len, $1);
// If the result was malloc()'d free it here
}
Wreszcie dołączyć plik nagłówkowy dla SWIG zawijać, korzystając z typemaps po prostu napisał:
%include "test.h"
testowałem to z:
public class run {
public static void main(String argv[]) {
System.loadLibrary("test");
obj_t obj = new obj_t();
short[] result = test.get_data(obj);
for (int i = 0; i < result.length; ++i) {
System.out.println(result[i]);
}
}
}
który produkował:
1
2
3
4
5
Dla porównania mogłeś owinięty:
void get_data(const obj_t *obj, short const **data, int *data_len);
również choć jeśli funkcja miał sposób do kwerendy rozmiaru bez ustawiania tablicy można owinąć to nieco mądrzejszy przeznaczając tablicę prawidłowej wielkości na Jawie bok. Aby to zrobić, chciałbyś napisać funkcję pośredniczącą w Javie, która zapytała o rozmiar, skonfigurowała wywołanie, a następnie zwróciła wynikową tablicę. Umożliwi to użycie GetShortArrayElements
/ReleaseShortArrayElements
dla potencjalnie 0 kopiowania.
To działa, ponieważ tablice w Javie są zasadniczo przekazywane przez referencję, np .:
public class ret {
public static void foo(int arr[]) {
arr[0] = -100;
}
public static void main(String argv[]) {
int arr[] = new int[10];
System.out.println(arr[0]);
foo(arr);
System.out.println(arr[0]);
}
}
Czy nadal szuka rozwiązania tego problemu? – Flexo
Tak, nadal nie wiem jak to zrobić – paleozogt
Odpowiedziałem na odpowiedź, która dokładnie odpowiada składni Java, o którą prosiłeś. Istnieje jednak możliwość odpowiedzi na oryginalną funkcję C, jeśli możesz zapytać o rozmiar bez wypełniania tablicy. Dodam to do mojej odpowiedzi, jeśli jesteś zainteresowany. – Flexo