-2

Trying to pass the following from Java code to a shared C library .so. I am very new to JNA if someone would point me i the right direction i would be very grateful.

The error i am getting is: 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])

The two relevant Objects/Structure:

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;
    }

The C sample stuct:


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;

The C file handling the data:

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

This is where the data gets handed from Java to C:

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

The full trace on the error is:

    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)

I have a feeling i am being a little naive regarding what JNA does so the issue will be my understanding of how i need to pass the data, so general advice on this specific implementation would certainly help me to understand what steps are required to use JNA. I have looked at a lot of the Tutorials out there and am currently looking through other answers on here. If you need any more information or context please just give me a shout.

docker dev
  • 91
  • 3
  • 10

1 Answers1

0

As the error says, you are missing a GetFieldOrder method.

From the documentation:

You must define getFieldOrder() to return a List of field names (Strings) indicating the proper order of the fields. When dealing with multiple levels of subclasses of Structure, you must add to the list provided by the superclass getFieldOrder() the fields defined in the current class.

You could also use the @Structure.FieldOrder annotation to provide field order instead of defining a method.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • Thank you that has helped nudge me past that error, however the following error seems to be having an issue with the constructor in my Motion object, Will these be an issue? How can i have a structure without a constructor as i need to build the object? Thank you for taking the time to help.: 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) at com.dataTypes.Motion.(Motion.java:19) – docker dev May 07 '20 at 13:49
  • Please use the search function and/or think before you ask. First (and only) hit on google is [this question](https://stackoverflow.com/questions/43018371/exception-in-thread-main-java-lang-illegalstateexception-array-fields-must-be) – Botje May 07 '20 at 14:20
  • Noted. Thank you – docker dev May 07 '20 at 14:36