I\'m a bit lost with typemaps in swig and how to use arrays. I have prepared a working example that uses arrays between java and c using swig, but i don\'t know if it is the
It's well documented here: http://swig.org/Doc3.0/SWIGDocumentation.html#Java_binary_char
The interface file below will generate byte[] method in java:
%apply (char *STRING, size_t LENGTH) { (const char data[], size_t len) }
%inline %{
void binaryChar1(const char data[], size_t len) {
printf("len: %d data: ", len);
for (size_t i=0; i<len; ++i)
printf("%x ", data[i]);
printf("\n");
}
%}
Don't discount carrays.i automatically. That said SWIG has some convenient typemaps already:
%module test
%apply(char *STRING, size_t LENGTH) { (char *str, size_t len) };
%inline %{
void some_func(char *str, size_t len) {
}
%}
Which produces a function in the Java interface:
public static void some_func(byte[] str)
i.e. it takes an array you can build in Java like normal and fills in the pointer and length for you. Almost for free.
Your code as it stands almost certainly leaks - you'd want to call free()
within the argout typemap to release the memory you allocated once it's been copied into the new Java array.
You can selectively apply typemaps by both the type and the name of the parameters. See this document for more on typemap matching rules. You can also request to explicitly use a typemap where it wouldn't otherwise be used with %apply
as in the example I showed above. (Actually it copies the typemaps, so that if you modified just one of them it doesn't replace it in the general case)
In general the typemaps for passing arrays from Java to C++ or working with arrays of known size are simpler than ones for returning from C++ to Java because the size information is more obvious.
My suggestion would be to plan on doing a lot of the allocation inside Java the allocation and designing your functions that might grow an array to operate in two modes: one that indicates the size needed and one that actually does the work. You might do that with:
ssize_t some_function(char *in, size_t in_sz) {
if (in_sz < the_size_I_need) {
return the_size_I_need; // query the size is pretty fast
}
// do some work on in if it's big enough
// use negative sizes or exceptions to indicate errors
return the_size_I_really_used; // send the real size back to Java
}
That would allow you to do something like the following in Java:
int sz = module.some_function(new byte[0]);
byte result[] = new byte[sz];
sz = module.some_function(result);
Note that with the default typemaps the new byte[0]
is needed because they don't allow null
to be used as an array - you could add typemaps that allow this if you wanted, or use %extend
to provide an overload that didn't need an empty array.