I'm a novice JNA developer so please forgive me if this question is trivial, but I'm struggling against dealing with C-lang struct object including an array of float with JNA. Currently I got a compile error.
I think the problem is the wrong way to initialize and assign FloatByReference instance (mys.Weights
) to mystruct class instance (mys
), and believe that Java code below should not be modified because JNAerator automatically generated it.
My C Code:
typedef struct
{
int n;
float *Weights;
} mystruct;
void testfunc(mystruct* mys){
printf(mys->Weights[0]);
}
public interface CLibrary extends Library {
public static final String JNA_LIBRARY_NAME = "test";
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CLibrary.JNA_LIBRARY_NAME);
public static final CLibrary INSTANCE = (CLibrary)Native.loadLibrary(CLibrary.JNA_LIBRARY_NAME, CLibrary.class);
and Java:
public interface CLibrary extends Library {
public static final String JNA_LIBRARY_NAME = "test";
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CLibrary.JNA_LIBRARY_NAME);
public static final CLibrary INSTANCE = (CLibrary)Native.loadLibrary(CLibrary.JNA_LIBRARY_NAME, CLibrary.class);
public static class mystruct extends Structure {
public int n;
public FloatByReference Weights;
protected List<? > getFieldOrder() {
return Arrays.asList("n", "Weights");
}
public mystruct(int n, JnaeratorTestLibrary.feature_t.ByReference Features, FloatByReference Weights) {
super();
this.n = n;
this.Features = Features;
this.Weights = Weights;
}
public mystruct(Pointer peer) {
super(peer);
}
public static class ByReference extends mystruct implements Structure.ByReference {
};
public static class ByValue extends mystruct implements Structure.ByValue {
};
};
void testfunc(CLibrary.mystruct mys);
}
public static void main(String[] args) {
mystruct mys = new mystruct();
mys.n = 10;
mys.Weights = new FloatByReference();
// Compile error raises.
mys.Weights = new float[4]; mys.Weights[0] = 1.0;
testfunc(mys);
}
Compile Error message:
Type mismatch: cannot convert from float[] to FloatByReference
Use Pointer
, then use Pointer.getFloatArray(0, n)
to extract the data you want.
You'll need to allocate Memory
and use Memory.write()
to write a Java primitive float array to native memory before assigning that memory to your structure field.
FloatByReference
is basically a pointer to one allocated float. JNAerator simply can't tell the difference between a pointer to a single float and a pointer to a buffer of floats (nor can a human without some additional context).