I want to use Java JNA to send an array of doubles to C, C will process data and write something into the array of doubles. Then I could use java to read it out. Btw C code is in a shared lib.
But My code does not work.
C function I am calling:
int swe_calc_ut(double *xx);
Java code to call that function:
(already establish the connection with C shared lib, the .so file That part has been tested and work fine. So ignore that part.)
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.*;
import com.sun.jna.Pointer;
// declare the C function
int swe_calc_ut(DoubleByReference xx);
// call the C function
DoubleByReference xx = new DoubleByReference();
swe_calc_ut(xx);
Error:
malloc(): invalid size (unsorted)
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
I guess it's related to pointer operation cause arrays are all pointer in C. But don't really know what to code.
CodePudding user response:
Try:
Pointer xx = New Memory(Native.getNativeSize(Double.class));
swe_calc_ut(xx);
CodePudding user response:
DoubleByReference
only allocates space for a single (8-byte) double
value, but you've specified an array.
JNA can handle primitive arrays just fine without any special treatment. See this example at JNA's PointersAndArrays doc:
// Original C declarations
void fill_buffer(int *buf, int len);
void fill_buffer(int buf[], int len); // same thing with array syntax
// Equivalent JNA mapping
void fill_buffer(int[] buf, int len);
So in your case, you could simply call
// declare the C function
int swe_calc_ut(double[] xx);
// call the C function
double[] xx = new double[size];
swe_calc_ut(xx);
Note that all you're really passing under the hood is a pointer to the start of the array, and there is no size information given. Either the API for the function specifies the size of the array, or there must be a way for you to communicate that size; otherwise the C side won't know where the array ends.
You could also pass the pointer by allocating a buffer using new Memory(Native.LONG_DOUBLE_SIZE * arraySize)
and setting/getting the double array with the associated Pointer
getters.