I'm a complete beginner at JNA
I am passing an empty structure to the function, which consists of structures nested in it. After calling the function, I expect the fields to be filled in, but the internal structure is always null
The native method looks like this:
SDK_API int LoadFile (char *fname, struct MyLoadFile *logfile, int reset);
The structure looks like this:
struct MyLoadFile {
struct Src *src
};
struct Src {
char *FileId;
unsigned long Version[4];
struct Msg *Messages;
struct Src *next;
};
My JNA function looks like this:
int LoadFile(ByteBuffer fname, MyLoadFile logfile, int reset);
I tried calling the function:
MyLoadFile file = new MyLoadFile ();
byte[] bytes = "D:/test/file".getBytes(StandardCharsets.US_ASCII);//Windows OS
ByteBuffer fName = ByteBuffer.allocateDirect(bytes.length);
fName.put(bytes);
fName.flip();
System.out.println("Ret code: " + MyLibrary.LoadFile(fName, file, 0));
**//file.src == null**
From the c++ code, I call the method as follows (and it works):
struct MyLoadFile logfile;
LoadFile ("D:/test/file", &logfile, true)
The structure classes are generated by JNAerator and look like this:
public class MyLoadFile extends Structure {
public Src.ByReference src;
public MyLoadFile() {
super();
}
protected List<String > getFieldOrder() {
return Arrays.asList("src");
}
public MyLoadFile(Src.ByReference src) {
super();
this.src= src;
}
public MyLoadFile(Pointer peer) {
super(peer);
read();
}
public static class ByReference extends MyLoadFile implements Structure.ByReference {}
public static class ByValue extends MyLoadFile implements Structure.ByValue { }
}
public class Src extends Structure {
public Pointer FileId;
public NativeLong[] Version = new NativeLong[4];
public Msg.ByReference Messages;
public ByReference next;
public Src() {
super();
}
protected List<String > getFieldOrder() {
return Arrays.asList("FileId", "Version", "Messages", "next");
}
public Src(Pointer FileId, NativeLong Version[], Msg.ByReference Messages,
ByReference next) {
super();
this.FileId = FileId;
if ((Version.length != this.Version.length))
throw new IllegalArgumentException("Wrong array size !");
this.Version = Version;
this.Messages = Messages;
this.next = next;
}
public Src(Pointer peer) {
super(peer);
read();
}
public static class ByReference extends Src implements Structure.ByReference {}
public static class ByValue extends Src implements Structure.ByValue {}
}
JNA does not automatically read the values at
Structure.ByReference
pointers, as there is a possibility that they may be null.You may be able to solve the problem by explicitly reading your
MyLoadFile
structure after your method call.Another solution here is to map
src
as aPointer
:Then after calling
LoadFile()
use that pointer to instantiate the nested structure with its constructor taking a pointer argument:You may need to do something similar to access the nested
Msg.ByReference
structure.