Windows DXGI Experiment

Daniel Jarabek jarabekit at gmail.com
Mon Feb 24 21:21:37 UTC 2025


Because of how Microsoft lays out the IID struct (int, short, short, 
byte[8]), shouldn't the UUID be this?

               buffer.
                   putInt(0x770aae78).
                   putInt(0x4dbaf26f).
                   putInt(0x3c2529a8).
                   putInt(0x87b3d183);

Running this in a Windows 11 VM, I get "Invocation result: 00000000" 
(which I assume is a success).

However, looking at the code, I don't see why the ByteBuffer is needed 
at all. Also, the IID/UUID struct can be represented using the panama 
API as a StructLayout:

         MemoryLayout.structLayout(
             ValueLayout.JAVA_INT.withName("data1"),
             ValueLayout.JAVA_SHORT.withName("data2"),
             ValueLayout.JAVA_SHORT.withName("data3"),
             MemoryLayout.sequenceLayout(8, 
ValueLayout.JAVA_BYTE).withName("data4")
         );

-DJ

On 2/24/25 13:58, Hugo De Vaan wrote:
> Greetings fellow developers,
>
> I've been trying to create a Java layer atop Microsoft's DXGI library 
> in an attempt to get Java to work with Desktop Duplication. 
> Unfortunately, I can't seem to create a DXGI factory. I can locate the 
> symbol just fine, and I've double checked the UUID value for the type 
> (using an earlier message in this mailing list, dating back to 
> September 2020). When invoking the method handle, I get the 0x80004002 
> HRESULT, which translates to "No such interface supported". I'm not 
> sure what I'm doing wrong here, so I would appreciate any help.
>
> [code]
> import java.lang.foreign.Arena;
> import java.lang.foreign.FunctionDescriptor;
> import java.lang.foreign.Linker;
> import java.lang.foreign.MemorySegment;
> import java.lang.foreign.SymbolLookup;
> import java.lang.foreign.ValueLayout;
> import java.lang.invoke.MethodHandle;
> import java.nio.ByteBuffer;
> import java.nio.ByteOrder;
> import java.util.HexFormat;
>
> public final class DXGIExperiment {
>     public static final void main(String[] args) {
>         try {
>             System.load("C:\\Windows\\System32\\dxgi.dll");
>
>             Linker linker = Linker.nativeLinker();
>
>               SymbolLookup symbols = SymbolLookup.libraryLookup(
>                   "C:\\Windows\\System32\\dxgi.dll", Arena.global());
>
>               /* MemoryLayout BIT128 = MemoryLayout.
>                       sequenceLayout(16, ValueLayout.JAVA_BYTE); */
>
>               /* Giving the 128bit UUID directly to the function doesn't
>                * work - the layout is not supported:
>                *
>                * FunctionDescriptor descriptor = FunctionDescriptor.of(
>                *   ValueLayout.JAVA_INT, BIT128, ValueLayout.ADDRESS);
>                */
>
>               FunctionDescriptor descriptor = FunctionDescriptor.of(
>               ValueLayout.JAVA_INT, ValueLayout.ADDRESS, 
> ValueLayout.ADDRESS);
>
>               MemorySegment createFactory =
>                   symbols.find("CreateDXGIFactory1").get();
>
>              MethodHandle handle = linker.
>                   downcallHandle(createFactory, descriptor);
>
>              System.out.println("Handle to CreateDXGIFactory1 created.");
>
>               byte[] uuidArray = new byte[16];
>               ByteBuffer buffer = ByteBuffer.wrap(uuidArray);
>               buffer.order(ByteOrder.LITTLE_ENDIAN);
>
>               buffer.
>                   putInt(0x770aae78).
>                   putInt(0xf26f4dba).
>                   putInt(0xa829253c).
>                   putInt(0x83d1b387);
>
>               MemorySegment factoryPointer =
>                   Arena.global().allocate(ValueLayout.ADDRESS);
>
>               MemorySegment uuidValue =
>                   Arena.global().allocate(16);
>
>               uuidValue.setAtIndex(ValueLayout.JAVA_INT, 0, 
> buffer.getInt(0));
>               uuidValue.setAtIndex(ValueLayout.JAVA_INT, 1, 
> buffer.getInt(4));
>               uuidValue.setAtIndex(ValueLayout.JAVA_INT, 2, 
> buffer.getInt(8));
>               uuidValue.setAtIndex(ValueLayout.JAVA_INT, 3, 
> buffer.getInt(12));
>
>               int hresult = (int) handle.
>                   invokeExact(uuidValue, factoryPointer);
>
>               System.out.println(
>                   "Invocation result: " +
>                   HexFormat.of().toHexDigits(hresult));
>               } catch (Throwable t) {
>                   t.printStackTrace();
>               }
>       }
> }
> [/code]
>
> PS: This was tried on Windows 10 Pro, 64 bit, build 19045 and running 
> GraalVM 21+35.1
>
> Regards,
> Hugo


More information about the panama-dev mailing list