Hello!
I am using JNA to wrap a C method that takes in nested structs. I believe that I am not properly storing the values in the Java Structures because I am seeing odd behavior with values shifting by one once the structs are passed to the C code.
C code:
gnc_pose_t diff_pose(gnc_pose_t pose1, gnc_pose_t pose2) {
// Print pose1
printf("Pos 1 = %1.3f %1.3f %1.3f\n",pose1.state.pos[0],pose1.state.pos[1],pose1.state.pos[2]);
printf("Vel 1 = %1.3f %1.3f %1.3f\n",pose1.state.vel[0],pose1.state.vel[1],pose1.state.vel[2]);
printf("Accel 1 = %1.3f %1.3f %1.3f\n",pose1.state.accel[0],pose1.state.accel[1],pose1.state.accel[2]);
// [print the rest of pose1 and pose2]
// [C code using pose1 and pose2]
}
C header file contains the following:
typedef double F64;
C header file contains the following:
typedef struct{
F64 pos[3];
F64 vel[3];
F64 accel[3];
} gnc_state_t;
typedef struct{
F64 quat[4];
F64 rate[3];
F64 accel[3];
} gnc_attitude_t;
typedef struct{
gnc_state_t state;
gnc_attitude_t attitude;
F64 time;
} gnc_pose_t;
extern gnc_pose_t diff_pose(gnc_pose_t pose1, gnc_pose_t pose2);
Java wrapper:
@FieldOrder({"pos", "vel", "accel"})
public static class gnc_state_t extends Structure {
public static class ByValue extends gnc_state_t implements Structure.ByValue {}
public double[] pos = new double[3];
public double[] vel = new double[3];
public double[] accel = new double[3];
}
@FieldOrder({"quat", "rate", "accel"})
public static class gnc_attitude_t extends Structure {
public static class ByValue extends gnc_attitude_t implements Structure.ByValue {}
public double[] quat = new double[4];
public double[] rate = new double[3];
public double[] accel = new double[3];
}
@FieldOrder({"state", "attitude", "time"})
public static class gnc_pose_t extends Structure {
public static class ByValue extends gnc_pose_t implements Structure.ByValue {}
public gnc_state_t.ByValue state;
public gnc_attitude_t.ByValue attitude;
public double time;
}
public interface GncMath_structs extends Library {
GncMath_structs INSTANCE = Native.load(sharedLibraryFilepath, GncMath_structs.class);
gnc_pose_t.ByValue diff_pose(gnc_pose_t.ByValue pose1, gnc_pose_t.ByValue pose2);
}
Java test code:
final double[] pos1 = {1, 2, 3};
final double[] vel1 = {4, 5, 6};
final double[] lin_accel1 = {7, 8, 9};
final double[] quat1 = {10, 11, 12, 13};
final double[] rate1 = {14, 15, 16};
final double[] ang_accel1 = {17, 18, 19};
final double time1 = 20;
final double[] pos2 = {21, 22, 23};
final double[] vel2 = {24, 25, 26};
final double[] lin_accel2 = {27, 28, 29};
final double[] quat2 = {30, 31, 32, 33};
final double[] rate2 = {34, 35, 36};
final double[] ang_accel2 = {37, 38, 39};
final double time2 = 40;
// assign vectors to structs
final JnaGncMath.gnc_state_t.ByValue state1 = new JnaGncMath.gnc_state_t.ByValue();
state1.pos = pos1;
state1.vel = vel1;
state1.accel = lin_accel1;
final JnaGncMath.gnc_state_t.ByValue state2 = new JnaGncMath.gnc_state_t.ByValue();
state2.pos = pos2;
state2.vel = vel2;
state2.accel = lin_accel2;
final JnaGncMath.gnc_attitude_t.ByValue attitude1 = new JnaGncMath.gnc_attitude_t.ByValue();
attitude1.quat = quat1;
attitude1.rate = rate1;
attitude1.accel = ang_accel1;
final JnaGncMath.gnc_attitude_t.ByValue attitude2 = new JnaGncMath.gnc_attitude_t.ByValue();
attitude2.quat = quat2;
attitude2.rate = rate2;
attitude2.accel = ang_accel2;
final JnaGncMath.gnc_pose_t.ByValue pose1 = new JnaGncMath.gnc_pose_t.ByValue();
pose1.state = state1;
pose1.attitude = attitude1;
pose1.time = time1;
final JnaGncMath.gnc_pose_t.ByValue pose2 = new JnaGncMath.gnc_pose_t.ByValue();
pose2.state = state2;
pose2.attitude = attitude2;
pose2.time = time2;
// call JNA method
final JnaGncMath.gnc_pose_t.ByValue pose3 = JnaGncMath.GncMath_structs.INSTANCE.diff_pose(pose1, pose2);
Values printed from the C code when the above Java test code is run:
Pose1:
Pos 1 = 1.000 2.000 3.000
Vel 1 = 4.000 5.000 6.000
Accel 1 = 7.000 8.000 9.000
Quat 1 = 10.000000000 11.000000000 12.000000000 13.000000000
Rate 1 = 14.000 15.000 16.000
Ang Accel 1 = 17.000 18.000 19.000
Time 1 = 21.000
Pose2:
Pos 2 = 22.000 23.000 24.000
Vel 2 = 25.000 26.000 27.000
Accel 2 = 28.000 29.000 30.000
Quat 2 = 31.000000000 32.000000000 33.000000000 34.000000000
Rate 2 = 35.000 36.000 37.000
Ang Accel 2 = 38.000 39.000 0.000
Time 2 = 0.000
The above values are the printed struct components as soon as the C code receives the structs. These values do not match what the structs were initialized with in the Java code. I have created a chart comparing the values in the structures in Java and in the C code:
I would appreciate any pointers on how to properly wrap these structs so their values are preserved when passed to the C code.
Thank you!