Search code examples
javajna

IllegalArgumentException when trying to access a JNA function


I am very new to JNA, and have a requirement of sending data to a legacy C system through Socket Connection from a Java System. I have been provided with .dll and a .h file.

I have to access a function in C system with .h file definition.

I loaded the .dll and when i access the function in dll i get IllegalArgumentException

public static void main(String[] args) {
    Arg arg = new Arg();
    ExampleDLL exampleDLL = ExampleDLL.INSTANCE;
    System.out.println(exampleDLL.someFunctionInDLL(arg));
}

public interface ExampleDLL extends Library {
    ExampleDLL INSTANCE = (ExampleDLL) Native.loadLibrary("exampleDLL.dll", ExampleDLL.class);

    int someFunctionInDLL(Arg arg);
}

public class Arg {
    public Byte[] var1 = new Byte[9];
    public Byte[] var2 = new Byte[5];
    // Getters and Setters....
}

From.h file:

typedef struct
{   
    char var1[9];   
    char var2[5];                   
}Arg;

int someFunctionInDLL(Arg *dr);

I think i have loaded the dll successfully but when i try to access the dll function :

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported argument type com.*.*.*.Arg at parameter 0 of function someFunctionInDLL

Help would be greatly appreciated. Kind of stuck on this for some time. Thanks in advance.


Solution

  • Welcome to Stack Overflow. You are getting the error because the argument your function is expecting is a pointer, but you are providing it a full Java class.

    int someFunctionInDLL(Arg *dr);
    

    The Arg class you defined should be a Structure. By default, JNA converts a Strcuture to its pointer (Structure.ByReference) when used as a function argument, and that's precisely what you want to happen here. You should be able to fix your code by making Arg extend Structure.

    Also, your mapping of bytes to the boxed Byte object is wrong: you need the primitive byte instead. So this should work (you'll need to add @FieldOrder annotation as well):

    public class Arg extends Structure {
        public byte[] var1 = new byte[9];
        public byte[] var2 = new byte[5];
    }