简体   繁体   中英

JNA : Correct mapping for COPYDATASTRUCT?

I have struggled a lot to make it work (a call to win32 API : SendMessage with WM_COPYDATA and COPYDATASTRUCT to hold the data) and as it works on my windows 7 computer now, I am wondering if my mapping is the good one and if there is no side effect of my solution ?

Here is my code :

/**
     * For usage with WM_COPYDATA
     * cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
     */
    long SendMessage(HWND hWnd, int msg, WPARAM wParam, COPYDATASTRUCT.ByReference lParam);

    int WM_COPYDATA = 0x004A;


//cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
class COPYDATASTRUCT extends Structure {

    public static class ByReference extends COPYDATASTRUCT implements Structure.ByReference {
    }

    public COPYDATASTRUCT() {
        super();
    }

    public int dwData;
    public long cbData;
    public Pointer lpData;

    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[] { "dwData", "cbData", "lpData" });
    }
}

And the calling code with 2 examples :

User32Extension.COPYDATASTRUCT.ByReference dataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
        String message = "Hello ! :-) !";
        Memory m = new Memory(message.length() + 1);
        m.setString(0, message);
        dataStruct.dwData = 10;
        dataStruct.cbData = message.length() + 1;
        dataStruct.lpData = m;
        dataStruct.write(); // writes to native memory the structure.
        result = user32.SendMessage(hwndTarget, // target hwnd.
                User32Extension.WM_COPYDATA, // copy data message.
                wparam, // current hwnd
                dataStruct // data by reference here
        );

        User32Extension.COPYDATASTRUCT.ByReference myDataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
        User32Extension.TEST_STRUCT myStruct = new User32Extension.TEST_STRUCT();
        //simple C structure here with 4 fields of C types int, char, char and long.
        myStruct.iNumber = 677;
        myStruct.cCode = 'E';
        myStruct.cCode2 = 'T';
        myStruct.lLong1 = new NativeLong(123456789L);
        myStruct.write();
        LOGGER.trace("myStruct (size=" + myStruct.size() + ")=" + myStruct.toString(true));

        myDataStruct.dwData = 11;
        myDataStruct.cbData = myStruct.size();
        myDataStruct.lpData = myStruct.getPointer();
        myDataStruct.write(); // writes to native memory the structure.
        result = user32.SendMessage(hwndTarget, // target hwnd.
                User32Extension.WM_COPYDATA, // copy data message.
                wparam, // current hwnd
                myDataStruct // data
        );

The key thing is this code compared to everything I have found on the net, is that COPYDATASTRUCT attribute cbData is of type long . If I set to int, it does not work (data is not correctly received in WndProc of the legacy C application). Is it correct to map a DWORD to a long java type ? Would it be better with a NativeLong ?

Another thing, that is to be noted, is the explicit call to Structure.write() for all the instantiated Structures (myStruct and myDataStruct). It is necessary in order to not have an empty memory before calling the SendMessage api. Do you think it is normal ? Or jna should call it automatically before invoking the SendMessage ?

Thanks in advance.

This native code:

typedef struct tagCOPYDATASTRUCT {
  ULONG_PTR dwData;
  DWORD     cbData;
  PVOID     lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;

maps to this JNA Structure definition:

public class COPYDATASTRUCT extends Structure {
    ULONG_PTR dwData;
    DWORD     cbData; // or use "int"
    Pointer   lpData;
}

The first and last fields will be of different size (and the structure will have different alignment/padding) depending on whether you're running 32- or 64-bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM