Reputation: 624
Assume I have the next C code snippet and I want to call it from Java using JNA.
typedef struct {
int bit_a;
int bit_b;
} * bit_handle;
bit_handler handle_open(const char *name, int prop);
For such a purpose I have written the next Java code snippet:
Java code:
public interface BitLibrary extends Library {
BitLibrary INSTANCE = (BitLibrary) Native.loadLibrary("bitlibrary", BitLibrary.class);
Pointer handler_open(char* name, int prop);
}
And it works perfectly, but instead of a Pointer I would like to retrieve a BitHandle object (see implementation below) by reference, because bit_handle in the previous C code is a pointer. How could I do that? I have tried something that looks like this example but I got a ClassCastException that says java.lang.reflect.Field cannot be cast to java.lang.Comparable and I am a bit clueless because from the logical point of view should work, but it doesn't. Am I missing something?
BitHandle implementation:
public static class BitHandle extends Structure {
public int bit_a;
public int bit_b;
public BitHandle(Pointer peer){
super(peer);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
protected List<?> getFieldOrder() {
List fieldList = new ArrayList(super.getFieldList());
fieldList.addAll(Arrays.asList("bit_a", "bit_b"));
return fieldList;
}
}
Upvotes: 0
Views: 119
Reputation: 624
Solution found, thanks to @user2864740 suggestions. The key was to disregard getFieldOrder() javadoc and implement it as below:
public class BitTest {
public interface BitLibrary extends Library {
BitLibrary INSTANCE = (BitLibrary) Native.loadLibrary("bit", BitLibrary.class);
public static class BitHandle extends Structure {
public int bit_a;
public int bit_b;
public static class ByReference extends BitHandle implements Structure.ByReference {}
@Override
protected List getFieldOrder() {
List<String> fieldList = new ArrayList<>();
fieldList.addAll(Arrays.asList("bit_a", "bit_b"));
return (List) fieldList;
}
}
BitHandle.ByReference bit_open(String drivername, int lun);
}
public static void main(String[] args) {
BitLibrary.BitHandle.ByReference pointer = BitLibrary.INSTANCE.Bit_open("CIBM_LINUX", 0);
}
}
Upvotes: 1