使用jna定义字段加载的java结构错误

4ktjp1zp  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(355)

我以前没有使用过jna,但我想我可以尝试使用我正在使用的第三方dll。我希望我能给出我用jna调用的函数的源代码,但遗憾的是我没有这个软件,所以我确定我可以发布什么。
我需要的结构相当长/复杂,只是一个警告。我没有包含加载这个结构所需的函数,因为它们看起来正在工作,没有问题。以下是原始c结构:

struct TSurfObjectInfos
{
  unsigned long ulSize;           // size of the structure

  int   Type;                     // studiable type

  char  strName[31];              // name of the studiable

  char  strOperatorName[31];      // name of the operator who
                                  // measured the studiable

  short nAcquisitionType;         // which kind of sensor has been used
                                  // for the measure

  short nTracking;                // 0: normal tracking
                                  // 1: extended tracking

  short nSpecialPoints;           // 0: normal
                                  // 1: non-measured points

  int   bAbsolute;                // FALSE: relatives values
                                  // TRUE: absolutes values

  float fGaugeResolution;         // 0: resolution not set

  long  nZMin;                    // min (resampled) value
  long  nZMax;                    // max (resampled) value

  long  nXCount;                  // number of points by column
  long  nYCount;                  // number of points by row
  long  nWCount;                  // number of points by depth (for hyperpectral measurements)

  float fXStep;                   // step
  float fYStep;                   // step
  float fZStep;                   // step

  float fXOffset;                 // offset
  float fYOffset;                 // offset
  float fZOffset;                 // offset

  char  strXAxisName[17];         // name of the X axis
  char  strYAxisName[17];         // name of the Y axis
  char  strZAxisName[17];         // name of the Z axis

  TUNIT tXAxisUnit;               // X axis unit
  TUNIT tYAxisUnit;               // Y axis unit
  TUNIT tZAxisUnit;               // Z axis unit

  char  strXAxisUnknownUnit[17];  // if unknown X unit, unit is present in this field
  char  strYAxisUnknownUnit[17];  // if unknown Y unit, unit is present in this field
  char  strZAxisUnknownUnit[17];  // if unknown Z unit, unit is present in this field

  int   bInverted;                // are the values inverted ?

  short nRectified;               // 

  short nSecond;                  // date-time of the measure
  short nMinute;
  short nHour;
  short nDay;
  short nMonth;
  short nYear;
  float fMeasureLength;           // length (in seconds) of the measure

  char  ClientInfo[128];          // client informations

  short nCommentSize;             // size in bytes of the comment

  //***T Axis******************
  //***only used with series***

  float fTStep;                   // step
  float fTOffset;                 // offset
  int   tTAxisUnit;               // T axis unit
  char  strTAxisUnknownUnit[14];  // if unknown T unit, unit is present in this field
  char  strTAxisName[14];         // name of the T axis

  //***T Axis******************
};
typedef struct TSurfObjectInfos TSurfObjectInfos;

下面是我的java实现:

@FieldOrder({ "unsignedSize",
              "type",
              "name",
              "operator",
              "sensorType",
              "trackingType",
              "specialPointType",
              "absolute",
              "gaugeResolution",
              "zMin", "zMax",
              "xCount", "yCount", "wCount",
              "fXStep", "fYStep", "fZStep",
              "xOffset", "yOffset", "zOffset",
              "xAxisName", "yAxisName", "zAxisName",
              "xAxisUnit", "yAxisUnit", "zAxisUnit",
              "strXAxisUnknownUnit", "strYAxisUnknownUnit", "strZAxisUnknownUnit",
              "inverted",
              "rectified",
              "second", "minute", "hour", "day", "month", "year", "fMeasureLength",
              "clientInfo",
              "commentSize",
              "tStep", "tOffset", "tAxisUnit", "strTAxisUnknownUnit", "tAxisName"})
public class StudiableInfo extends Structure {

  private static final int DATA_SIZE = 339;

  /**
   * Unsigned byte size of structure.
   */
  @Getter public NativeLong unsignedSize = new NativeLong(DATA_SIZE, true);

  /**
   * Type of surface.
   */
  @Getter public int type;

  /**
   * Name of surface (maximum length of 31).
   */
  @Getter public char[] name = new char[31];

  /**
   * Name of operator who measured the surface (maximum length of 31).
   */
  @Getter public char[] operator = new char[31];

  /**
   * Type of sensor used for measuring the surface.
   */
  @Getter public short sensorType;

  /**
   * Type of tracking used in measurements.
   */
  @Getter public short trackingType;

  /**
   * Special point type, and whether there are non-measured points.
   */
  @Getter public short specialPointType;

  /**
   * Defines if surface has absolute values.
   */
  @Getter public boolean absolute;

  /**
   * Gauge resolution value. Defined as 0 if resolution not set.
   */
  @Getter public float gaugeResolution;

  /**
   * Minimum (resampled) value.
   */
  @Getter public NativeLong  zMin = new NativeLong();
  /**
   * Maximum (resampled) value.
   */
  @Getter public NativeLong  zMax = new NativeLong();

  /**
   * Number of points by column.
   */
  @Getter public NativeLong xCount = new NativeLong();
  /**
   * Number of points by row.
   */
  @Getter public NativeLong  yCount = new NativeLong();
  /**
   * Number of points by depth (for hyperpectral measurements).
   */
  @Getter public NativeLong  wCount = new NativeLong();

  /**
   * X-axis step value.
   */
  @Getter public float fXStep;
  /**
   * Y-axis step value.
   */
  @Getter public float fYStep;
  /**
   * Z-axis step value.
   */
  @Getter public float fZStep;

  /**
   * X-axis offset.
   */
  @Getter public float xOffset;
  /**
   * X-axis offset.
   */
  @Getter public float yOffset;
  /**
   * X-axis offset.
   */
  @Getter public float zOffset;

  /**
   * Name of the X-axis (max size of 17 bytes).
   */
  @Getter public char[] xAxisName = new char[17];
  /**
   * Name of the Y-axis (max size of 17 bytes).
   */
  @Getter public char[] yAxisName = new char[17];
  /**
   * Name of the Z-axis (max size of 17 bytes).
   */
  @Getter public char[] zAxisName = new char[17];

  /**
   * X-axis measurement units.
   */
  @Getter public int xAxisUnit;
  /**
   * Y-axis measurement units.
   */
  @Getter public int yAxisUnit;
  /**
   * Z-axis measurement units.
   */
  @Getter public int zAxisUnit;

  /**
   * If unknown X-axis unit from enum, unit is present in this field (max size of 17 bytes).
   */
  @Getter public char[] strXAxisUnknownUnit = new char[17];
  /**
   * If unknown Y-axis unit from enum, unit is present in this field (max size of 17 bytes).
   */
  @Getter public char[] strYAxisUnknownUnit = new char[17];
  /**
   * If unknown Z-axis unit from enum, unit is present in this field (max size of 17 bytes).
   */
  @Getter public char[] strZAxisUnknownUnit = new char[17];

  /**
   * Defines if the studiable values are inverted.
   */
  @Getter public boolean inverted;

  /**
   * Defines if the studiable is levelled.
   */
  @Getter public short rectified;

  /**
   * Seconds value at recorded time of measurement.
   */
  @Getter public short second;
  /**
   * Minutes value at recorded time of measurement.
   */
  @Getter public short minute;
  /**
   * Hour value at recorded time of measurement.
   */
  @Getter public short hour;
  /**
   * Day at recorded time of measurement.
   */
  @Getter public short day;
  /**
   * Month at recorded time of measurement.
   */
  @Getter public short month;
  /**
   * Year at recorded time of measurement.
   */
  @Getter public short year;
  /**
   * Length (in seconds) of the measure.
   */
  @Getter public float fMeasureLength;

  /**
   * Client information (max size of 128 bytes).
   */
  @Getter public char[] clientInfo = new char[128];

  /**
   * Size in bytes of the comment.
   */
  @Getter public short commentSize;

  //***T Axis******************
  //***only used with series***
  /**
   * Step value of T-axis.
   */
  @Getter public float tStep;
  /**
   * Offset of T-axis.
   */
  @Getter public float tOffset;
  /**
   * T-axis measurement units.
   */
  @Getter public int tAxisUnit;
  /**
   * If unknown T-axis unit from enum, unit is present in this field (max size of 14 bytes).
   */
  @Getter public char[] strTAxisUnknownUnit = new char[14];
  /**
   * Name of the T-axis (max size of 14 bytes).
   */
  @Getter public char[] tAxisName = new char[14];

  //***T Axis******************
}

在我看来,一切都很好,但当实际加载和查看结构时,唯一正确的字段是 type 成员。从那时起,其他所有字段都将显示为无效或垃圾数据。但是,它是一致的,总是输出相同的无效数据集。
我担心这可能是因为导入功能在内部工作。你会注意到有一个 ulSize 我猜可以用来Map结构中的内存的字段?因此,一旦使用了jna或java的内存处理,函数内部可能就没有将内存Map到正确的位置。虽然我对jna还很陌生,但我不确定这是否是一个可能的问题。
我也在想,可能在本机c和 long 类型和jna NativeLong ? 但我还是不太确定。我甚至试过换新的 NativeLong 与…在一起 long 但似乎还是不起作用。
如果我能提供更多信息,请告诉我。我不想过多的信息本来是无用的。

rjjhvcjd

rjjhvcjd1#

问题最可能的根源是使用java的 char c语言的Map char . 他们不一样。 java 的 char 是字符的2字节utf-16Map,而在c中是 char 是一个单字节。
有关更多信息,请参见概述中的jna的类型Map参考。
你的选择 NativeLong 对于c long 一般来说,对于跨平台代码是可以的。
我不知道你在说什么 TUNIT Map到,但如果是4字节类型 int Map很好。

相关问题