My aim is to create a data structure which should have the following representation in the memory:
int countOfElements; // 4 bytes
int time_1; // 4 bytes
double price_1; // 8 bytes
int time_2; // 4 bytes
double price_2; // 8 bytes
int time_3; // 4 bytes
double price_3; // 8 bytes
. . . . .
int time_n; // 4 bytes, n = countOfElements
double price_n; // 8 bytes, n = countOfElements
Unfortunately, I am not free to choose representation (field order and type) of this structure in the memory, because it relates another process on the OS. The data structure is intended to be placed on the shared memory by using WinAPI functions, and the purpose of this data structure is data exchange. Thus, I'll be also needed to get the pointer to this data structure in java... So, my effort to realize this data structure looks like:
import java.util.List;
import java.util.Arrays;
import com.sun.jna.Structure;
public class TQuote extends Structure {
public int time;
public double price;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"time", "price"});
}
}
public class TSharedArray extends Structure {
public int countOfElements;
public TQuote[] elements;
public TSharedArray(int size) {
super();
countOfElements = size;
elements = new TQuote[size];
for (int i = 0; i < size; i++) elements[i] = new TQuote();
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"countOfElements", "elements"});
}
}
Though, my attempts to instantiate the structure TSharedArray structure = new TSharedArray(10);
throws an exception:
/*
Invalid Structure field in class xxx$TSharedArray, field name 'elements' (class xxx$TQuote): Can't instantiate class xxx$TQuote (java.lang.InstantiationException: xxx$TQuote)
java.lang.IllegalArgumentException: Invalid Structure field in class xxx$TSharedArray, field name 'elements' (class xxx$TQuote): Can't instantiate class xxx$TQuote (java.lang.InstantiationException: xxx$TQuote)
at com.sun.jna.Structure.validateField(Structure.java:962)
at com.sun.jna.Structure.validateField(Structure.java:954)
at com.sun.jna.Structure.validateFields(Structure.java:972)
at com.sun.jna.Structure.<init>(Structure.java:186)
at com.sun.jna.Structure.<init>(Structure.java:180)
at com.sun.jna.Structure.<init>(Structure.java:167)
at com.sun.jna.Structure.<init>(Structure.java:159)
at xxx$TSharedArray.<init>(xxx.java:35)
at xxx.onStart(xxx.java:57)
at java.lang.Thread.run(Unknown Source)
*/
Java code in the xxx.java line #35 is super();
Any ideas, how to fix it?
Additionally, I noticed one strange thing... Let's assume, we have three structures and each of these structures contains of two fields:
public class TIntInt extends Structure {
public int int1;
public int int2;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"int1", "int2"});
}
}
public class TDblDbl extends Structure {
public double dbl1;
public double dbl2;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"dbl1", "dbl2"});
}
}
public class TIntDbl extends Structure {
public int int1;
public double dbl1;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"int1", "dbl1"});
}
}
The first one (TIntInt) have size as expected of 2*4=8 bytes, the second one (TDblDbl) have size as expected of 2*8=16 bytes, but the third (TIntDbl - it's the same as TQuote) have size of 16 bytes instead of expected of 4+8=12. Why?:
System.out.println("TIntInt.size()=" + new TIntInt().size()); // 8 bytes, Ok
System.out.println("TDblDbl.size()=" + new TDblDbl().size()); // 16 bytes, Ok
System.out.println("TIntDbl.size()=" + new TIntDbl().size()); // 16 bytes!!! Why?