如何用 JNA 正确调用这个 DLL? EXCEPTION_ACCESS_VIOLATION

How to properly call this DLL with JNA? EXCEPTION_ACCESS_VIOLATION

我正在尝试使用 Java 和来自 Windows 的 JNA 访问 C DLL 的方法。

有时一切顺利,但有时我会得到一个 EXCEPTION_ACCESS_VIOLATION(它似乎是随机的,当它工作时,当它不工作时,更多关于这个在底部)。我已经阅读了一些关于此异常的主题,但没有成功。

这是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);
}

这是他们装饰(或不装饰)的方式:

SpellInit
SpellTerminate
SpellSuggestChar
_SpellGetUdr@0
_SpellSetOptions@4

Dependency Walker 在我打开它时抛出这两个错误:

错误:由于隐式依赖模块中缺少导出函数,至少有一个模块具有未解析的导入。 错误:找到具有不同 CPU 类型的模块。

但是这个 DLL 派生自另一个运行良好的 DLL(虽然它是从 VB 代码调用的)并且也会抛出相同的两个错误。

最后我是这样称呼它的:

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();
  }

我也尝试过扩展 Library 而不是 StdCallLibrary(我想 StdCallLibrary 应该是最好的选择,不是吗?),但结果是一样的:调用 SpellSuggestChar 或 SpellGetUdr 时崩溃。这两个函数的共同点是都需要从sqlite数据库中读写。

无论如何,它不会总是崩溃,而且它取决于 computer/user 执行它。例如,如果从域计算机中的管理员帐户执行,它崩溃的频率低于在非特权帐户中执行的情况。

我知道有很多可能的错误原因,但现在我只想知道你们中的一些人是否可以在 DLL 导出或 JNA 代码中发现错误(第一次使用它),所以我可以排除一些可能性。

谢谢。

Technomage 说得对,他说所有方法都应该声明为使用 stdcall,而不是混合使用和不使用 stdcall 的方法。但这只是问题的一半。

最终解决方案来自更改 SQLite 编译选项,特别是 -DTHREADSAFE 参数。激活后一切正常。

干杯。