<div dir="ltr">Hi Panama team,<div><br></div><div>This code calling a Windows API fails:</div><div><br></div><div><font face="monospace">        try (var arena = Arena.ofConfined()) {<br>            var transfer = _WINUSB_SETUP_PACKET.allocate(arena);<br>            WinUsb.WinUsb_ControlTransfer(NULL, transfer, NULL, 0, NULL, NULL);<br>        }<br></font></div><div><br></div><div>It throws an exception:</div><div><br></div><div><font face="monospace">    Exception in thread "main" java.lang.ExceptionInInitializerError<br>        at org.example.gen.WinUsb.WinUsb_ControlTransfer(WinUsb.java:121)<br>        at org.example.App.main(App.java:53)<br>    Caused by: java.lang.IllegalArgumentException: Unsupported layout: 1%s2<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkSupported(AbstractLinker.java:293)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkLayoutRecursive(AbstractLinker.java:186)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkStructMember(AbstractLinker.java:181)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkLayoutRecursive(AbstractLinker.java:196)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkLayout(AbstractLinker.java:175)<br>        at java.base/java.lang.Iterable.forEach(Iterable.java:75)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.checkLayouts(AbstractLinker.java:167)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.downcallHandle0(AbstractLinker.java:97)<br>        at java.base/jdk.internal.foreign.abi.AbstractLinker.downcallHandle(AbstractLinker.java:84)<br>        at org.example.gen.WinUsb$WinUsb_ControlTransfer.<clinit>(WinUsb.java:82)<br>        ... 2 more<br></font></div><div><br></div><div>Both WinUsb_ControlTransfer() and _WINUSB_SETUP_PACKET have been generated with jextract and are correct as far as I can tell.</div><div><br></div><div>Two aspects are special in this call:</div><div><ol><li> _WINUSB_SETUP_PACKET is a packed struct with an alignment of 1 byte.</li><li>_WINUSB_SETUP_PACKET is passed by value.</li></ol><div>Is it a restriction of FFM that unaligned structs cannot be passed by value (it works if the natural alignment of 2 bytes is used)? Or what is the issue here?</div></div><div><br></div><div>For reference, here is the relevant jextract generated code:</div><div><br></div><div>WINUSB_SETUP_PACKET (<a href="https://learn.microsoft.com/en-us/windows/win32/api/winusb/ns-winusb-winusb_setup_packet">https://learn.microsoft.com/en-us/windows/win32/api/winusb/ns-winusb-winusb_setup_packet</a>):</div><div><br></div><div><font face="monospace">    private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(<br>        WinUsb.C_CHAR.withName("RequestType"),<br>        WinUsb.C_CHAR.withName("Request"),<br>        WinUsb.align(WinUsb.C_SHORT, 1).withName("Value"),<br>        WinUsb.align(WinUsb.C_SHORT, 1).withName("Index"),<br>        WinUsb.align(WinUsb.C_SHORT, 1).withName("Length")<br>    ).withName("_WINUSB_SETUP_PACKET");<br></font></div><div><br></div><div>WinUsb_ControlTransfer (<a href="https://learn.microsoft.com/en-us/windows/win32/api/winusb/nf-winusb-winusb_controltransfer">https://learn.microsoft.com/en-us/windows/win32/api/winusb/nf-winusb-winusb_controltransfer</a>):</div><div><br></div><div><font face="monospace">    public static final FunctionDescriptor DESC = FunctionDescriptor.of(<br>        WinUsb.C_INT,<br>        WinUsb.C_POINTER,<br>        _WINUSB_SETUP_PACKET.layout(),<br>        WinUsb.C_POINTER,<br>        WinUsb.C_LONG,<br>        WinUsb.C_POINTER,<br>        WinUsb.C_POINTER<br>    );<br></font></div><div><br></div><div>Regards,</div><div>Manuel</div><div><br></div></div>