Search code examples
javawinapidlljna

Calling a Scanner Win32 DLL from Java


We have to connect to a scanner and perform some functions from our Java application. The customer has provided us Win32 Scanner Library Specification.

Example: BOOL GetScannerInfo(ScannerInfo *scanner)

Structure ScannerInfo is defined in a header file.

#define  scannerMAX 10  // Maximum number of connected scanners  
typedef struct{  
        int count;// -> Number of scanners connected  
    BYTE host_no[scannerMAX];   // -> Host adapter number  
    BYTE scsi_id[scannerMAX];   // -> SCSI ID of the scanner  
}ScannerInfo;  

For example, if two scanners, SCSI IDs 1 and 2, are connected to one host adapter, the return values will be as follows:

count=2  
host_no[0]=0,   host_no[1]=0  
scsi_id[0]=1,   scsi_id[1]=2  

Now, we have to call this function and get scanner related information from Java. Got started with JNA for the first time and here is the code.

public interface ScannerInterface extends Library {

    public boolean GetScannerInfo(?);
            /* ? = They have a pointer of a custom object.What should be passed here
             */

}

public static void main(String[] args) {

    ScannerInterface lib = (ScannerInterface) Native.loadLibrary("in64.dll", 
            ScannerInterface.class);        

    System.out.println(lib.GetScannerInfo(?));

}

I am stuck on how to pass the parameters that the Win32 function expects from JNA.


Solution

  • You can define the Java class ScannerInfo that maps to your struct like this:

    public interface ScannerInterface extends Library {
        public static class ScannerInfo extends Structure {
            public static class ByReference 
                extends ScannerInfo 
                implements Structure.ByReference {}
    
            public int count;
            public byte[] host_no = new byte[10];
            public byte[] scsi_id = new byte[10];
        }
    
        public int GetScannerInfo(ScannerInfo.ByReference scanner);
    }
    

    Then call it like this:

    ScannerInterface lib = (ScannerInterface) Native.loadLibrary("in64.dll", 
            ScannerInterface.class);        
    
    ScannerInterface.ScannerInfo.ByReference scanner = 
        new ScannerInterface.ScannerInfo.ByReference();
    int retval = lib.GetScannerInfo(scanner);            
    // check retval in case of error
    int count = scanner.count;
    // etc. etc.