Search code examples
javawindowsjna

JNA - Map Native Windows Data Types (IN and OUT parameters)


I am trying to use the Windows API of an IP-USB-Hub (AnywhereUSB) in Java with JNA. I managed to load the dll and now I have to map the functions. I have the header file which declares an enum and some functions like shown as follows:

typedef enum AWUSB_STATUS_tag{
    AWUSB_STATUS_CONNECTED,
    AWUSB_STATUS_ALREADY_CONNECTED,
    AWUSB_STATUS_INVALID_PARAMETER,
    AWUSB_STATUS_TIMEOUT,
    AWUSB_STATUS_CANCELLED,
    AWUSB_STATUS_SUCCESS,
    ...
}AWUSB_STATUS, *PAWUSB_STATUS;

and

AWUSB_STATUS AwUsbGetConnectionStatus (
   IN   LPCWSTR Hub,
   OUT  PDWORD  IpAddress,
   OUT  PAWUSB_STATUS   Status,
   IN   DWORD   Timeout,
   IN   HANDLE  hEvent OPTIONAL
);

What irritates me, are the IN, OUT and OPTIONAL parameters. I do not really understand what those tags mean. How do I handle them in Java?

So far I declared them like this in Java:

    public static interface AWUSB_STATUS_tag {
        public static final int AWUSB_STATUS_CONNECTED = 0;
        public static final int AWUSB_STATUS_ALREADY_CONNECTED = 1;
        public static final int AWUSB_STATUS_INVALID_PARAMETER = 2;
        public static final int AWUSB_STATUS_TIMEOUT = 3;
        ...
    };

    int AwUsbGetConnectionStatus(WString Hub, int IpAdress, IntBuffer Status, int Timeout, Pointer hEvent);

Are the Mappings correct? And what do I need to do to be able to call the function?

Thanks in advance!


Solution

  • Generally, "OUT" means that you need to pass a pointer value, usually a variable reference of the form &my_variable. JNA provides XXXByReference types for this purpose for primitives, and you can define your own. You create an instance of that type of parameter, and then use getValue() to retrieve the "result", e.g.

    IntByReference iref = new IntByReference();
    lib.myCall(iref);
    int value = iref.getValue();
    

    You can use String in place of WString if you set the default type mapper to do so (refer to the default initializations of other windows API library mappings).

    MyLib mylib = (MyLib)Native.loadLibrary("mylib", W32APIOptions.DEFAULT_OPTIONS);    
    

    For this native code:

    AWUSB_STATUS AwUsbGetConnectionStatus (
       IN   LPCWSTR Hub,
       OUT  PDWORD  IpAddress,
       OUT  PAWUSB_STATUS   Status,
       IN   DWORD   Timeout,
       IN   HANDLE  hEvent OPTIONAL
    );
    
    // Java mapping
    int AwUsbGetConnectionStatus(String Hub, DWORDByReference IpAddress, IntByReference Status, DWORD Timeout, HANDLE hEvent);
    

    Those "OUT" parameters need to be of pointer type.