仅使用Java11在Windows 10上具有64位dll的无效内存访问

时间:2019-06-27 18:06:19

标签: java jna

我有一个Java应用程序,它使用jna调用64位第三方DLL与扫描仪(具有本机64位驱动程序)进行通信。 Windows 10 / java11 / jna的组合出现了我收到的无效的内存访问错误,而其他组合没有收到。

此代码在以下所有情况下均能正常运行,没有错误:

  • Windows 7/64位Java 8运行时
  • Windows 7/64位Java 11运行时
  • Windows 10/64位Java 8运行时

我正在使用最新最好的jna(5.3.1),并且还尝试了较旧的版本,结果相同。

/* Open Scanner */
EZT.TWAIN_SetHideUI(true);
if (EZT.TWAIN_GetSourceList()) {
    if (!EZT.TWAIN_OpenDefaultSource()) {
        throw new RuntimeException("Cannot open scanner");
    }
 }

 /* Retrieve scanner capabilities for resolution */
 int hcon = EZT.TWAIN_Get(EZLibrary.ICAP_XRESOLUTION);
 if (hcon != 0) {
     int resolutions[] = new int[EZT.CONTAINER_ItemCount(hcon)];
     ...
 }
 .....
 private interface EZLibrary extends Library {
     int ICAP_XRESOLUTION = 4376;

     void TWAIN_SetHideUI(boolean bHide);
     boolean TWAIN_GetSourceList();
     boolean TWAIN_OpenDefaultSource();
     int TWAIN_Get(int uCap);
     int CONTAINER_ItemCount(int hcon);
 }

在此示例中,对“ EZT.CONTAINER_ItemCount(hcon)”的调用返回了无效的内存访问错误。但是,如果此代码是我的大型应用程序的一部分,而不是本示例应用程序的一部分,则相同的代码序列将在“ EZT.TWAIN_OpenDefaultSource()”上引发无效内存访问错误。

因此,总而言之:

  • windows 7 / java 8:符合预期结果
  • windows 7 / java 11:预期结果
  • windows 10 / java 8:预期结果
  • Windows 10 / Java 11:

    java.lang.Error:无效的内存访问     在com.sun.jna.Native.invokeInt(本机方法)     在com.sun.jna.Function.invoke(Function.java:426)     在com.sun.jna.Function.invoke(Function.java:361)     在com.sun.jna.Library $ Handler.invoke(Library.java:265)     在com.sun.jna.Native $ 3.invoke(Native.java:1202)     位于$ Proxy0.CONTAINER_ItemCount(未知来源)

我的问题变成Win 10 / java 11的JNA出现问题了,还是第三方代码中出现了什么,或者我做错了什么?

1 个答案:

答案 0 :(得分:0)

我最终找到了解决方案。

我不确定为什么,但是对于64位,我的JNA实现需要:

Long TWAIN_Get(int uCap);
Long TWAIN_Acquire(int hwndApp);

必须使用32位:

Integer TWAIN_Get(int uCap);
Integer TWAIN_Acquire(int hwndApp);

为处理这两个问题,我只使用:

Number hcon = EZT.TWAIN_Get(EZTwainPro.ICAP_XRESOLUTION);

这样做可以解决无效的内存访问。我知道这是因为返回的int是一个无符号的int,但是我不确定为什么“ long”实现只能在64位而不是32位运行时上运行。为了同时工作,必须有所不同。同样,仅在win10而不是win7上才需要“长”实现,但是在win7上也可以使用。