Reputation: 75
I am working on JNA to return a nested structure pointer on a native function call. The nested structure has members of type unsigned char, struct. I was able to read the primitive types but struck up in processing the nested structure member e.g. OBISCODE in Response. My nested Structure looks like below:
typedef struct ObisCode
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
} OBISCODE;
typedef struct Response
{
unsigned char result;
OBISCODE obis;
} RESPONSE;
and native function as:
RESPONSE* getStruct(OBISCODE * obis)
My Java code calling this native function as below:
package struct;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
public class JNATest {
static {
Native.register("StructTest");
}
public static class OBISCODE {
private Pointer pointer;
public OBISCODE() {
long memory = Native.malloc(6);
pointer = new Pointer(memory);
}
public OBISCODE(Pointer pointer) {
this.pointer = pointer;
}
Pointer getPointer() {
return pointer;
}
int getA() {
return pointer.getByte(0);
}
int getB() {
return pointer.getByte(1);
}
int getC() {
return pointer.getByte(2);
}
int getD() {
return pointer.getByte(3);
}
int getE() {
return pointer.getByte(4);
}
int getF() {
return pointer.getByte(5);
}
void setA(byte a) {
pointer.setByte(0, a);
}
void setB(byte b) {
pointer.setByte(1, b);
}
void setC(byte c) {
pointer.setByte(2, c);
}
void setD(byte d) {
pointer.setByte(3, d);
}
void setE(byte e) {
pointer.setByte(4, e);
}
void setF(byte f) {
pointer.setByte(5, f);
}
void free() {
Native.free(Pointer.nativeValue(pointer));
}
}
public static native void printStruct(Pointer obis);
public static native Pointer getStruct(Pointer obis);
/**
* @param args
*/
public static void main(String[] args) {
try {
struct.JNATest.OBISCODE obis = new struct.JNATest.OBISCODE();
obis.setA( (byte) 0);
obis.setB( (byte) 0);
obis.setC( (byte) 8);
obis.setD( (byte) 0);
obis.setE( (byte) 0);
obis.setF( (byte) 255);
Pointer ptr = obis.getPointer();
System.out.println("ptr = " + ptr.toString());
printStruct(obis.getPointer());
Pointer resptr = getStruct(obis.getPointer());
Response response = new Response(resptr);
System.out.println("result = " + response.getResult());
System.out.println("1=" + resptr.getInt(1) + "2=" + resptr.getInt(2)
);
obis.free();
} catch (UnsatisfiedLinkError e) {
System.out.println("Exception" + e);
}
}
}
My equivalent native structure Response class as below
package struct;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
public class Response {
private Pointer pointer;
public Response() {
long memory = Native.malloc(6);
pointer = new Pointer(memory);
}
public Response(Pointer pointer) {
this.pointer = pointer;
}
Pointer getPointer() {
return pointer;
}
int getResult() {
return pointer.getByte(0);
}
int getOBIS() {
return pointer.getByte(1);
}
void setResult(byte a) {
pointer.setByte(0, a);
}
void setOBIS(byte b) {
pointer.setByte(1, b);
}
void free() {
Native.free(Pointer.nativeValue(pointer));
}
}
I was running this test in Redhat Linux and the output obtained as below
result = 12
1=5242882=2048
Please correct me if I am missing something in Java code to process the structure. Any help is greatly appreciated? Thanks in advance.
Upvotes: 1
Views: 1762
Reputation: 10069
JNA provides direct support for Structures.
For example:
public class ObisCode extends Structure
{
public byte a;
public byte b;
public byte c;
public byte d;
public byte e;
public byte f;
protected List getFieldOrder() { return Arrays.asList(new String[] { "a", "b", "c", "d", "e", "f" }); }
public OBISCODE() { }
public OBISCODE(Pointer p) { super(p); read(); }
}
public class Response extends Structure
{
public byte result;
public OBISCODE obis;
protected List getFieldOrder() { return Arrays.asList(new String[] { "result", "obis" }); }
public Response() { }
public Response(Pointer p) { super(p); read(); }
}
Upvotes: 2