Search code examples
javac++jna

Allocating WinDef.RECT struct in JNA


I have a C function (compiled into a DLL) that takes a WinDef.RECT object and prints out the four co-ordinates:

DllExport void Test(RECT rect)
{
    printf("Rect: %i, %i, %i, %i", rect.top, rect.left, rect.bottom, rect.right);
}

On the Java (JNA) side, I'm attempting to pass it a WinDef.RECT as follows:

WinDef.RECT rect = new WinDef.RECT();
rect.bottom=0;
rect.left=0;
rect.right=0;
rect.top=0;
jna.INSTANCE.Test(rect);

However, I just get nonsense numbers out (which aren't consistent and vary every time), eg:

Rect: -857788769, 11343200, 8044544, 8044544

I'm assuming that I'm not defining the RECT correctly on the JNA side (the C++ function is fine called from other native functions in the same dll), but beyond that I'm a bit stuck!


Solution

  • I had a useful answer over on the JNA mailing list:

    Your native signature is asking for struct and your JNA mapping defaults to struct* semantics. Change your native sig or use Structure.ByValue; struct* is preferred unless you explicitly need otherwise.

    In my case I need the native library to remain unchanged, so the solution was declaring a subclass of WinDef.RECT and tagging it with Structure.ByValue:

    public static class RectByValue extends WinDef.RECT implements Structure.ByValue {}
    

    This could then be used in place of WinDef.RECT, and all appears to work without an issue.

    Note that while this fix worked ok for me, other(s) have reported otherwise - as in the comment below, switching types to LPRECT is another potential fix.