无法使用结构的 ByReference 从本机获取数据

问题描述 投票:0回答:1

我是 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 {}
  }
java jna jnaerator
1个回答
0
投票

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
结构。

© www.soinside.com 2019 - 2024. All rights reserved.