我是 JNA 的初学者
我将一个空结构传递给函数,该结构由嵌套在其中的结构组成。调用函数后,我期望字段被填充,但内部结构始终为空
本机方法如下所示:
SDK_API int LoadFile (char *fname, struct MyLoadFile *logfile, int reset);
结构如下:
struct MyLoadFile {
struct Src *src
};
struct Src {
char *FileId;
unsigned long Version[4];
struct Msg *Messages;
struct Src *next;
};
我的 JNA 函数如下所示:
int LoadFile(ByteBuffer fname, MyLoadFile logfile, int reset);
我尝试调用该函数:
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**
从 C++ 代码中,我按如下方式调用该方法(并且它有效):
struct MyLoadFile logfile;
LoadFile ("D:/test/file", &logfile, true)
结构类由 JNAerator 生成,如下所示:
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 不会自动读取目标指针处的值,因为它们有可能为空。当读取
src
的值时,您会遇到 来自 Structure 类的代码:
// Get the current value only for types which might need to be preserved
Object currentValue = (Structure.class.isAssignableFrom(fieldType)
|| Callback.class.isAssignableFrom(fieldType)
|| (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(fieldType))
|| Pointer.class.isAssignableFrom(fieldType)
|| NativeMapped.class.isAssignableFrom(fieldType)
|| fieldType.isArray())
? getFieldValue(structField.field) : null;
由于该字段属于标记接口类型
Structure.ByReference
,因此它不能分配给上述任何类型,因此您将得到 null
。
这里最简单的解决方案是将
src
映射为 Pointer
:
@FieldOrder ({ "src" })
public class MyLoadFile extends Structure {
public Pointer src;
public static class ByReference extends MyLoadFile implements Structure.ByReference {}
}
然后在调用
LoadFile()
之后,使用该指针实例化嵌套结构,其构造函数采用指针参数:
MyLibrary.LoadFile(fName, file, 0);
Src src = new Src(file.src);
您可能需要执行类似的操作才能访问嵌套的
Messages
结构。