【问题标题】:Mapping JNA Java to Native C Shared Library将 JNA Java 映射到本机 C 共享库
【发布时间】:2020-08-22 16:08:52
【问题描述】:

尝试将以下内容从 Java 代码传递到共享 C 库 .so。我对 JNA 很陌生,如果有人能指出我正确的方向,我将不胜感激。

我得到的错误是:java.lang.Error: Structure.getFieldOrder() on class com.dataTypes.TCIMUEvent does not provide enough names [0] ([]) to match declared fields [11] ([accel , accelValid, gyro, gyroValid, mag, magValid, pressure, pressureValid, temperature, temperatureValid, time])

两个相关的对象/结构:

public class Motion extends Structure {

    public TCIMUEvent tcimuEvent;
    public int Status;
    public double userHeadingDeg;
    public float rotationMode;

    public Motion() {
    }

    public TCIMUEvent getTcimuEvent() {
        return tcimuEvent;
    }

    public Motion(TCIMUEvent tcimuEvent, int status, double userHeadingDeg, float rotationMode) {
        this.tcimuEvent = tcimuEvent;
        Status = status;
        this.userHeadingDeg = userHeadingDeg;
        this.rotationMode = rotationMode;
    }
public class TCIMUEvent extends Structure {

    public double time;
    public float[] accel;
    public boolean accelValid;
    public float[] mag;
    public boolean magValid;
    public float[] gyro;
    public boolean gyroValid;
    public float pressure;
    public boolean pressureValid;
    public float temperature;
    public boolean temperatureValid;

    public TCIMUEvent(double time, float[] accel, boolean accelValid, float[] mag, boolean magValid, float[] gyro, boolean gyroValid, float pressure, boolean pressureValid, float temperature, boolean temperatureValid) {
        this.time = time;
        this.accel = accel;
        this.accelValid = accelValid;
        this.mag = mag;
        this.magValid = magValid;
        this.gyro = gyro;
        this.gyroValid = gyroValid;
        this.pressure = pressure;
        this.pressureValid = pressureValid;
        this.temperature = temperature;
        this.temperatureValid = temperatureValid;
    }

C 示例结构:


typedef struct {
  double time;
  double accel[3];
  bool accelValid;
  double mag[3];
  bool magValid;
  double gyro[3];
  bool gyroValid;
  double pressure;
  bool pressureValid;
  double temperature;
  bool temperatureValid;
} T_imuDataSample_t;

处理数据的 C 文件:

void HandleImuEvent(T_imuDataSample_t *imuDataSample, int *status,
  double *userHeadingDeg, StrapdownStreaming_RotationMode *currentRotateMode)
{

这是数据从 Java 传递到 C 的地方:

HandleImuEvent(motion.getTcimuEvent(), motion.getStatus(), motions.getUserHeadingDeg(), motions.getRotationMode());

错误的完整跟踪是:

    java.lang.Error: Structure.getFieldOrder() on class com.dataTypes.TCIMUEvent does not provide enough names [0] ([]) to match declared fields [11] ([accel, accelValid, gyro, gyroValid, mag, magValid, pressure, pressureValid, temperature, temperatureValid, time])
        at com.sun.jna.Structure.getFields(Structure.java:1077)
        at com.sun.jna.Structure.deriveLayout(Structure.java:1232)
        at com.sun.jna.Structure.calculateSize(Structure.java:1159)
        at com.sun.jna.Structure.allocateMemory(Structure.java:401)
        at com.sun.jna.Structure.ensureAllocated(Structure.java:377)
        at com.sun.jna.Structure.ensureAllocated(Structure.java:367)
        at com.sun.jna.Structure.size(Structure.java:434)
        at com.sun.jna.Structure.size(Structure.java:1137)
        at com.sun.jna.Native.getNativeSize(Native.java:1354)
        at com.sun.jna.Structure.getNativeSize(Structure.java:2253)
        at com.sun.jna.Structure.getNativeSize(Structure.java:2243)
        at com.sun.jna.Structure.validateField(Structure.java:1209)
        at com.sun.jna.Structure.validateFields(Structure.java:1222)
        at com.sun.jna.Structure.<init>(Structure.java:200)
        at com.sun.jna.Structure.<init>(Structure.java:193)
        at com.sun.jna.Structure.<init>(Structure.java:180)
        at com.sun.jna.Structure.<init>(Structure.java:172)
        at com.dataTypes.Motion.<init>(Motion.java:17)

我觉得我对 JNA 所做的事情有点天真,所以问题在于我对我需要如何传递数据的理解,所以关于这个具体实施的一般建议肯定会帮助我理解需要哪些步骤使用 JNA。我已经查看了很多教程,目前正在查看其他答案。如果您需要更多信息或上下文,请给我留言。

【问题讨论】:

  • 问题是什么?
  • 好点对不起我会添加我得到的错误。

标签: java c java-native-interface jna java-native-library


【解决方案1】:

正如错误所说,您缺少GetFieldOrder 方法。

来自the documentation

您必须定义 getFieldOrder() 以返回字段名称(字符串)列表,指示字段的正确顺序。在处理 Structure 的多级子类时,必须将当前类中定义的字段添加到超类 getFieldOrder() 提供的列表中。

您也可以使用@Structure.FieldOrder annotation 来提供字段顺序而不是定义方法。

【讨论】:

  • 谢谢你帮助我克服了那个错误,但是下面的错误似乎是我的 Motion 对象中的构造函数有问题,这些会是一个问题吗?当我需要构建对象时,如何在没有构造函数的情况下拥有结构?感谢您抽出宝贵时间提供帮助。:java.lang.IllegalStateException: Array fields must be initialized at com.sun.jna.Structure.deriveLayout(Structure.java:1288) ......... at com. sun.jna.Structure.(Structure.java:172) 在 com.dataTypes.Motion.(Motion.java:19)
  • 请使用搜索功能和/或三思而后行。谷歌上的第一个(也是唯一一个)点击是this question
  • 注明。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-31
  • 2011-01-25
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多