Search code examples
javawindowsdlljna

How to properly call this DLL with JNA? EXCEPTION_ACCESS_VIOLATION


I am trying to access the methods of a C DLL with Java and JNA from Windows.

Sometimes everything goes fine, but other times I get an EXCEPTION_ACCESS_VIOLATION (it seems to be random when it works and when not, more about this at the bottom). I have read some topics about this exception, but to no success.

This is the part of the exports in the DLL:

#ifdef __WIN32__
extern "C"{
  __declspec (dllexport) int __stdcall SpellInit(const char *path_dic, const char *path_volg);
  __declspec (dllexport) int __stdcall SpellTerminate(void **lista);
  __declspec (dllexport) LPSTR __stdcall SpellSuggestChar(const unsigned char *palabra);
  __declspec (dllexport) LPSTR SpellGetUdr(void);
  __declspec (dllexport) int SpellSetOptions(int option);
}

This is how they get decorated (or not):

SpellInit
SpellTerminate
SpellSuggestChar
_SpellGetUdr@0
_SpellSetOptions@4

Dependency Walker throws these two errors when I open it:

Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module. Error: Modules with different CPU types were found.

But this DLL derives from another one that works fine (though it is called from a VB code) and which also throws the same two errors.

And finally this is how I am calling it:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
import java.util.HashMap;

public class Test_DLL {
  public interface ORTCLI extends StdCallLibrary {        
    ORTCLI INSTANCE = (ORTCLI) Native.loadLibrary("ORTCLI", ORTCLI.class, new HashMap(){{
        put("SpellGetUdr","_SpellGetUdr@0");
        put("SpellSetOptions","_SpellSetOptions@4");
    }});

    int SpellInit(String path_dic, String path_volg);
    String SpellSuggestChar(String pal);
    int SpellAddUdr(String pal);
    String SpellGetUdr();
    int SpellTerminate();
  }

I have also tried to extend Library instead of StdCallLibrary (I guess StdCallLibrary should be the best choice, isn't it?), but the result is the same: it crashes when calling SpellSuggestChar or SpellGetUdr. The common factor between these two functions is that they have to read and write from a sqlite database.

Anyway, it does not crash always and besides it is dependent on which computer/user executes it. For instance, if executed from an Administrator account in a domain computer it crashes less often than if executed in a non-privileged account.

I know that there are many possible causes for the error, but for now I would just want to know if some of you can spot an error in the DLL exports or in the JNA code (first time with it), so I can rule out some possibilities.

Thanks.


Solution

  • Technomage is right when he says that all methods should be declared to use stdcall instead of mixing methods with stdcall and without. But that was only half of the problem.

    Finally the solution came from changing a SQLite compilation option, specifically the -DTHREADSAFE parameter. Everything started to work fine after it was activated.

    Cheers.