I have a method in C++ that takes an array of doubles as an argument. I'm calling this method from Java and need to pass an array of doubles. The C++ routine reads and modifies the values of the array and I need those updated values in Java. How do I do this?
For example, take the C++ routine:
void myMethod( double *values, int size ) {
for ( int i=0; i < size; i++ ) {
values[i] = 2*values[i];
}
}
And the Java code:
double[] values = { 1.3, 1.1 };
myMethod(values,values.length);
System.out.println(values[0]); // prints 2.6
I guess a call to myMethod cannot be made like the call above... or can it? And what is necessary in Swig to make this work. If I cannot make a call like the one above, how do I get my values to the C++ code?
You can pass arrays to a method just like normal variables. When we pass an array to a method as an argument, actually the address of the array in the memory is passed (reference). Therefore, any changes to this array in the method will affect the array.
Use the Arrays class to both sort and display the entire array. Next, pass the array as the sole argument to a method that doubles each element of the array and then returns the array. Use a foreach loop to show all elements in the returned array on one line separated by a single space.
Arrays can be passed to other methods just like how you pass primitive data type's arguments. To pass an array as an argument to a method, you just have to pass the name of the array without square brackets. The method prototype should match to accept the argument of the array type.
To pass an array to a function, just pass the array as function's parameter (as normal variables), and when we pass an array to a function as an argument, in actual the address of the array in the memory is passed, which is the reference.
Use carrays.i!
See Swig docs on carrays
%include carrays.i
%array_functions( double, double_array )
These two lines create the following code in my module:
public static SWIGTYPE_p_double new_double_array(int nelements) {
long cPtr = SimulatorModuleJNI.new_double_array(nelements);
return (cPtr == 0) ? null : new SWIGTYPE_p_double(cPtr, false);
}
public static void delete_double_array(SWIGTYPE_p_double ary) {
SimulatorModuleJNI.delete_double_array(SWIGTYPE_p_double.getCPtr(ary));
}
public static double double_array_getitem(SWIGTYPE_p_double ary, int index) {
return SimulatorModuleJNI.double_array_getitem(SWIGTYPE_p_double.getCPtr(ary), index);
}
public static void double_array_setitem(SWIGTYPE_p_double ary, int index, double value) {
SimulatorModuleJNI.double_array_setitem(SWIGTYPE_p_double.getCPtr(ary), index, value);
}
Which allows me to use C arrays in Java... this solves my needs and is the best solution for my problem. Thanks everyone for your answers!
SWIG typemaps should allow this. The SWIG 2.0 documentation shows this example in Python.
With Java, you would use JNI code inside your SWIG typemap. JNI provides methods Get/ReleaseArrayElements. I'm guessing you could get a native array in a typemap(in)
, then release it in a typemap(argout)
.
Another approach would be to copy your array into a std::vector, using the existing SWIG typemap in std_vector.i.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With