<div dir="ltr">As Jorn pointed out to me, I missed another indirection in my previous post. I guess it shows that I originally came from a pure C environment before my Java days and so have little to no experience in C++ specifically. It's not as if in C we never had pointers to pointers, but I feel C++ really takes it to another level. This is probably going to trip me up a few more times, but that's okay, I am now at least aware of it and it will be the first thing I check when my code runs into "FMM over C++" bugs.<br><br>Anyway, the following snippet is taken from a fully working class and uses the post incubation FFM API (replacing things like NativeScope, MemoryAddress, MemoryAccess, and so forth from the 2020 example). I thought I'd post it here to help other people who might Google their way into examples or tutorials from the incubation era (an unavoidable risk for any JDK preview projects, I guess).<br><br>private static MemorySegment DEFINE_GUID(<br>    Arena arena, <br>    int data1, int data2, int data3, <br>    int data4_0, int data4_1, int data4_2, int data4_3, <br>    int data4_4, int data4_5, int data4_6, int data4_7) {<br><br>    MemorySegment refIID = IID.allocate(arena);<br>    IID.Data1(refIID, data1);<br>    IID.Data2(refIID, (short)data2);<br>    IID.Data3(refIID, (short)data3);<br>        <br>    MemorySegment data4 = IID.Data4(refIID);<br>    IID.Data4(data4, 0, (byte) data4_0);<br>    IID.Data4(data4, 1, (byte) data4_1);<br>    IID.Data4(data4, 2, (byte) data4_2);<br>    IID.Data4(data4, 3, (byte) data4_3);<br>    IID.Data4(data4, 4, (byte) data4_4);<br>    IID.Data4(data4, 5, (byte) data4_5);<br>    IID.Data4(data4, 6, (byte) data4_6);<br>    IID.Data4(data4, 7, (byte) data4_7);<br>          <br>    return refIID;<br>}<br><br>static final MemorySegment IID_IDXGIFactory1 = <br>    DEFINE_GUID(<br>        Arena.global(), <br>        0x770aae78, 0xf26f, 0x4dba, <br>        0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87);<br><br>public static final void main(String[] args) {<br>    Linker linker = Linker.nativeLinker();<br><br>    SymbolLookup symbols = SymbolLookup.<br>        libraryLookup(<br>        "C:\\Windows\\System32\\dxgi.dll", <br>        arena);<br>    <br>    try (Arena arena = Arena.ofConfined()) {<br>        MemorySegment factoryPointer = <br>            arena.allocate(ValueLayout.ADDRESS);<br><br>        int hresult = dxgi_h.CreateDXGIFactory1(<br>            IID_IDXGIFactory1, factoryPointer);<br><br>        System.out.println(<br>            "CreateDXGIFactory: " + <br>            HexFormat.of().toHexDigits(hresult));<br><br>        MemorySegment factory = <br>            IDXGIFactory1.reinterpret(<br>                factoryPointer.get(dxgi_h.C_POINTER, 0L), <br>                arena, <br>                null);<br><br>        MemorySegment factoryVtable = <br>            IDXGIFactory1.lpVtbl(factory);<br><br>        MemorySegment EnumAdapters1 = <br>            IDXGIFactory1Vtbl.EnumAdapters1(factoryVtable);<br><br>        MemorySegment adapterPointer = <br>            arena.allocate(dxgi_h.C_POINTER);<br><br>        hresult = IDXGIFacotry1Vtbl.EnumAdapters1.invoke(<br>            EnumAdapters1, factory, 0, adapterPointer);<br><br>        System.out.println(<br>            "EnumAdapters: " + <br>            HexFormat.of().toHexDigits(hresult));<br><br>        MemorySegment adapter = <br>            IDXGIAdapter1.reinterpret(<br>                adapterPointer.get(dxgi_h.C_POINTER, 0L), <br>                arena, <br>                null);<br><br>        MemorySegment adapterVtable = <br>            IDXGIAdapter1.lpVtbl(adapter);<br><br>        MemorySegment GetDescriptor1 = <br>            IDXGIAdapter1Vtbl.GetDesc1(adapterVtable);<br><br>        MemorySegment descriptorPointer = <br>            DXGI_ADAPTER_DESC.allocate(arena);<br><br>        hresult = IDXGIAdapter1Vtbl.GetDesc1.invoke(<br>            GetDescriptor1, adapter, descriptorPointer);<br><br>        System.out.println(<br>            "GetDescriptor: " + <br>            HexFormat.of().toHexDigits(hresult));<br> <br>        MemorySegment cstring = DXGI_ADAPTER_DESC1.<br>            Description(descriptorPointer);<br><br>        String jstring = cstring.getString(<br>            0, StandardCharsets.UTF_16LE);<br><br>        System.out.println("Adapter[0]: " + jstring);<br>    } catch (Throwable t) {<br>        t.printStackTrace();<br>    }<br>}<br><br>This should print the descriptor of the first adapter (for example: "NVIDIA GeForce RTX 4060"). Anyone trying this in a headless environment such as a cloud node might want to be careful, because I haven't tested whether or not a software adapter would also qualify for this function (if it doesn't, I expect this snippet will crash your JVM).<br><br>Thanks again for the help, getting over the first hurdles makes all the difference between being able to continue a project at all or staying completely stuck. I still got (and will get) some things wrong, but with the basic parts up and running, I will be able to figure out problems for myself.<br><br>Kind regards,<br>Hugo<br></div>