Search code examples
javacjna

How do I properly initialize array fields within a `Structure` in JNA?


I have a Struct in C i want to represent in java with JNA:

typedef struct SmallStrcut {
     unit32_t a[128];
}

typedef struct BigStruct {
     SmallStruct b;
     SmallStruct c;
}

And the following function:

void getBigStruct(BigStruct bigStruct);

I have the following Structs in Java:
SmallStruct:

public class SmallStruct extends Structure {
      public static ByValue extends SmallStruct implements Structure.ByValue {
           public int a[];
           public ByValue() {}
      }
}

BigStruct:

public class BigStruct extends Structure {
        public static ByValue extends BigStruct implements Structure.ByValue {
               public SmallStruct b;
               public SmallStruct c;
               public ByValue() {}
          }

This is my main:

BigStruct.ByValue big = new BigStruct.ByValue();
SmallStruct.ByValue x1 = new SmallStruct.ByValue();
x1.a = new int[128];
x1.a[0] = 123;
SmallStruct.ByValue x2 = new SmallStruct.ByValue();
x2.a = new int[128];
x2.a[0] = 456;

big.b = x1;
big.c = x2;

And when i debug this code i watched the BigStruct object and only the b member is initialized. c array is all zero.
Its like the first SmallStruct ovverides the second SmallStruct memory area.

How can i transfer the two SmallStruct to construct the BigStruct properly ?


Solution

  • When defining Structure fields, JNA defaults to by value semantics, so you can just use Structure.

    It is up to you to initialize any array fields within your Structure, since JNA has no way of knowing how big you want them to be.

    public class SmallStruct extends Structure {
       public int a[] = new int[128];
    }
    

    Note that the contents of those arrays will not by synched with native memory until you call Structure.read() or Structure.write() (these calls are performed automatically by JNA when you call a native method which uses a Structure argument).