I\'m trying to figure out what SWIG Interface file change is needed in order to handle the getFoo returns a pointer that points to an array of a custom structure (sender_id_t).
The simplest solution to this doesn't involve writing any JNI at all - in effect it's method 2. So what I did was use carrays.i to expose a very basic interface and then written a small bit of Java to make the public
view of it more usable/intuitive. The key thing is you need to supply a way of bringing together the knowledge of the array and the length of it. I've put together a minimal complete example to illustrate, it returns a Java array, but it could equally work for an ArrayList
or any collection you like.
Firstly a header file, with an inline implementation for compactness:
#ifndef TEST_H
#define TEST_H
struct Foo {
int v;
};
inline static struct Foo *getFoo() {
static struct Foo r[] = {{0},{1},{2}};
return r;
}
inline static unsigned short numFoo() {
return 3;
}
#endif
This is then wrapped with:
%module test
%{
#include "test.h"
%}
%include <carrays.i>
%array_functions(struct Foo, foo_array);
%rename(getFooImpl) getFoo;
%javamethodmodifiers getFoo() "private";
%javamethodmodifiers numFoo() "private";
%include "test.h"
%pragma(java) modulecode=%{
public static Foo[] getFoo() {
final int num = numFoo();
Foo ret[] = new Foo[num];
Foo result = getFooImpl();
for (int i = 0; i < num; ++i) {
ret[i] = foo_array_getitem(result, i);
}
return ret;
}
%}
Where we make rename the getFoo()
from the header file and make it and the corresponding numFoo()
private
, i.e. implementation details.
Using these two private functions we can then write a real, public Foo[] getFoo()
, that calls these two and then copies the results into an actual array of known size.
I tested this with:
public class main {
public static void main(String[] argv) {
System.loadLibrary("test");
Foo[] foos = test.getFoo();
System.out.println(foos[2].getV());
}
}
In my view this solution is cleaner than the corresponding JNI based example - it's simpler to write and harder to introduce bugs which makes it more maintainable. Any Java or C programmer that looks at it can pretty much see what's going on. It's probably not much worse in terms of performance and probably not going to be a big chunk of time on some critical path - if benchmarks show it to be a problem then it's still easy to go down the JNI road later.
For completeness on the "making it private
" aspect you might also want to do something like:
%javamethodmodifiers foo_array_getitem "private";
%ignore foo_array_setitem;
%ignore delete_foo_array;
%ignore new_foo_array;
%include <carrays.i>
%array_functions(struct Foo, foo_array);
To hide all of the functions which get generated by the %array_functions
macro.