Reputation: 21
I am trying to make a connection between a c++ dll and my java project by JNA. The dll.h is in this gitHub: dll.h.
EXTERN_C DLLEXPORT int STDCALL SolveBoard(
struct deal dl,
int target,
int solutions,
int mode,
struct futureTricks * futp,
int threadIndex);
struct deal
{
int trump;
int first;
int currentTrickSuit[3];
int currentTrickRank[3];
unsigned int remainCards[DDS_HANDS][DDS_SUITS];
};
struct futureTricks
{
int nodes;
int cards;
int suit[13];
int rank[13];
int equals[13];
int score[13];
};
I am fresh to JNA and c++, I have tried to code in Java like this:
public interface DllAl extends StdCallLibrary{
DllAl instanceDll = (DllAl)Native.loadLibrary("dds",DllAl.class);
public int SolveBoard(deal deal,int target,int solutions,int mode, futureTricks fut,int threadIndex);
public int PrintFut(char title[],futureTricks fut);
public static class deal extends Structure{
public int trump;
public int first;
public int currentTrickSuit[] = new int [3];
public int currentTrickRank[] = new int [3];
public int remainCards[][] = new int[4][4];
public static class ByReference extends deal implements Structure.ByReference {}
public static class ByValue extends deal implements Structure.ByValue {}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"trump", "first", "currentTrickSuit", "currentTrickRank","remainCards"});
}
}
public static class futureTricks extends Structure{
public int nodes;
public int cards;
public int suit[] = new int [13];
public int rank[] = new int [13];
public int equals[] = new int[13];
public int score[] = new int[13];
public static class ByReference extends futureTricks implements Structure.ByReference {}
public static class ByValue extends futureTricks implements Structure.ByValue {}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"nodes", "cards", "suit", "rank","equals","score"});
}
}
} However, it returns mistakes:
Exception in thread "main" java.lang.NullPointerException
at java.lang.reflect.Array.getLength(Native Method)
at com.sun.jna.Native.getNativeSize(Native.java:1162)
at com.sun.jna.Structure.getNativeAlignment(Structure.java:1360)
at com.sun.jna.Structure.getNativeAlignment(Structure.java:1385)
at com.sun.jna.Structure.deriveLayout(Structure.java:1221)
at com.sun.jna.Structure.calculateSize(Structure.java:1053)
at com.sun.jna.Structure.allocateMemory(Structure.java:380)
at com.sun.jna.Structure.ensureAllocated(Structure.java:356)
at com.sun.jna.Structure.ensureAllocated(Structure.java:346)
at com.sun.jna.Structure.write(Structure.java:737)
at com.sun.jna.Structure.autoWrite(Structure.java:2047)
at com.sun.jna.Function.convertArgument(Function.java:512)
at com.sun.jna.Function.invoke(Function.java:305)
at com.sun.jna.Library$Handler.invoke(Library.java:236)
at com.sun.proxy.$Proxy0.SolveBoard(Unknown Source)
at DllAl.main(DllAl.java:98)
Upvotes: 1
Views: 384
Reputation: 9091
JNA does not map 2D (or 3D, 4D, etc.) arrays. If you need to map a 2D array you should replace it with a 1D array and then write your own code to translate.
You need to change this line:
public int remainCards[][] = new int[4][4];
to:
public int remainCards[] = new int[16];
Then add a method which translates the 2D coordinates (e.g., hands, suits) to the 1D index (e.g., 4*hands + suits).
Upvotes: 1