首页 > 解决方案 > JNA:结构的 char 数组成员的计算大小令人惊讶

问题描述

有人可以向我解释为什么以下结构大小为 16 吗?

public class StringStruct extends Structure {
  public char[] data = new char[4];

  public StringStruct() {}

  @Override
  protected List<String> getFieldOrder() {
    return Collections.singletonList("data");
  }
}



public class Main {

  public static void main(String[] args) {

    StringStruct ss = new StringStruct();

    // Prints StringStruct: 16
    // I was expecting 4...
    System.out.println("StringStruct: " + ss.size());

  }

}

我想对拥有数据的结构进行建模

typedef struct {
   char data[4];
} StringStruct_s

如果我改用字节数组,它会返回预期值。尽管如此,char 数组的大小还是让我感到惊讶。该字段是否被解释为拥有一个编码的 String ?所以,我用各种显式编码 ( -Djna.encoding="...") 启动了这个可执行文件,看看它是否有效果。不用找了...

标签: javacjna

解决方案


JNA中,Java char 可以映射到16-bit或者32-bit字符。

这意味着你有:32/8 * 4 = 16

https://github.com/java-native-access/jna/blob/master/www/Mappings.md

在你的机器上尝试这样的事情

int main() {
  printf("%ld\n",sizeof(wchar_t));
}

更新

正如@Daniel 所提到的,值得注意的是,C基于映射char应该通过byte.

对于这堂课

interface CLibrary extends Library {

  public CLibrary.Data.ByVal GetDataValue();
  public CLibrary.Data.ByRef GetDataAllocated();

  public class Data extends Structure {

    public static final List<String> FIELDS =  List.of("array");

    public static class ByVal extends Data implements Structure.ByValue {}

    public static class ByRef extends Data implements Structure.ByReference {}

    public byte[] array = new byte[4];

    @Override
    protected List<String> getFieldOrder() {
      return FIELDS;
    }
  }
}

你会得到预期的大小:4


推荐阅读