Search code examples
javac++dlljna

Invalid memory access


I wrote a DLL that has to be used in Java:

public interface MyInterface extends Library {
   public void GetDllVersion(char[] buffer, int bufferLen);
   ...
}

MyInterface instance=(MyInterface) Native.loadLibrary(basename,MyInterface.class);
char[] buffer=new char[20];
instance.GetDllVersion(buffer,buffer.length);

The corresponding C Code is

void __declspec(dllexport) GetDllVersion(char *buffer,int bufferLen) {
  ...
}

I also turned jna.debug_load on to see some output. The lib is loaded as expected, but the call to GetDllVersionfails with

Exception in thread "main" java.lang.Error: Invalid memory access
   at com.sun.jna.Native.invokeVoid(Native Method)
   at com.sun.jna.Function.invoke(Function.java:367)
   at com.sun.jna.Function.invoke(Function.java:315)
   at com.sun.jna.Library$Handler.invoke(Library.java:212)
   at com.sun.proxy.$Proxy0.GetDllVersion(Unknown Source)
   at Main.main(Main.java:34)

Dependency Walker shows that the DLL exports this function.

How to find out what exactly is wrong with the function call?


Solution

  • Your problem is due to a mismatch in the size of the Java 16 bit char vs the size of the C 8 bit char. One solution is to pass data as a byte[].

    public void GetDllVersion(byte[] buffer, int bufferLen);
    

    and

    __declspec(dllexport) void GetDllVersion(byte *buffer,int bufferLen) {
    

    Another solution is to use wide char on the native side.

    __declspec(dllexport) void GetDllVersion(wchar_t *buffer,int bufferLen) {