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). Without any special SWIG Interface code, I get just the pointer on the Java side. How can I turn that pointer into something I can loop or iterate over (in Java) so that I can get each sender_id_t id value? Appreciate any suggestions.
C Structure:
typedef unsigned char id_v1_t[32];
typedef id_v1_t id_t;
%rename (Sample) sender_id_t_;
struct sender_id_t_ {
id_t id;
uint32_t phy_idx;
};
C Function:
//This will return a pointer to an array of sender_id_t data. The number of elements is retrieved from a separate call.
sender_id_t* getFoo(resultset_t* resultset);
Exception:
[exec] test_wrap.c: In function `new_foo_array':
[exec] test_wrap.c:785: error: invalid application of `sizeof' to incomplete type `sender_id_t_'
[exec] test_wrap.c: At top level:
[exec] test_wrap.c:792: error: return type is an incomplete type
[exec] test_wrap.c: In function `foo_array_getitem':
[exec] test_wrap.c:793: error: invalid use of undefined type `struct sender_id_t_'
[exec] test_wrap.c:793: error: dereferencing pointer to incomplete type
[exec] test_wrap.c:793: warning: `return' with a value, in function returning void
[exec] test_wrap.c: At top level:
[exec] test_wrap.c:795: error: parameter `value' has incomplete type
[exec] test_wrap.c: In function `foo_array_setitem':
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
publicview 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 anArrayListor any collection you like.Firstly a header file, with an inline implementation for compactness:
This is then wrapped with:
Where we make rename the
getFoo()from the header file and make it and the correspondingnumFoo()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:
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:To hide all of the functions which get generated by the
%array_functionsmacro.