【问题标题】:Invalid Memory Access with 64 bit dll's on windows 10 only with java11Windows 10 上 64 位 dll 的无效内存访问仅使用 java 11
【发布时间】:2019-06-27 18:06:19
【问题描述】:

我有一个 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 是否存在问题,或者是第三方代码中的问题,还是我做错了什么?

【问题讨论】:

    标签: java jna


    【解决方案1】:

    我确实找到了解决方案。

    我不完全确定为什么,但对于 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 是一个 unsigned int,但我不完全确定为什么“long”实现只适用于 64 位而不是 32 位运行时。它必须有所不同才能同时发挥作用。此外,“long”实现仅适用于 win10,而不是 win7,但它也适用于 win7。

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      相关资源
      最近更新 更多