JNA: Computed size of char array member of a struct is surprising

Can someone explain to me why the following structure size is 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());

  }

}

I want to model structures which own their data

typedef struct {
   char data[4];
} StringStruct_s

If I use a byte array instead, it returns the expected value. Still, the char array size is really surprising to me. Is the field interpreted as owning an encoded String ? So, I launched this executable with various explicit encodings (-Djna.encoding="...") to see if it had an effect. No change...

Upvotes: 0

Views: 448

Answers (1)

Oo.oO
Oo.oO

Reputation: 13405

In JNA, Java char can be mapped to either 16-bit or 32-bit character.

It means that you have: 32/8 * 4 = 16

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

Try something like this on your machine

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

Update

As mentioned by @Daniel, it's worth noting that mapping C based char should be done via byte.

For this class

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

you will get size as expected: 4

Upvotes: 2

Related Questions