繁体   English   中英

我如何使用 JNA 处理 Java 内部内存访问

[英]How can i handle a Java internal memory access using JNA

C代码是

extern int APIENTRY LSGetDocData(
    short          hConnect,
    HWND           hWnd,
    unsigned long  *NrDoc,
    LPSTR          FilenameFront,
    LPSTR          FilenameBack,
    LPSTR          Reserved1,      // not used must be NULL         
    LPSTR          Reserved2,      // not used must be NULL
    LPHANDLE       *FrontImage,
    LPHANDLE       *BackImage,
    LPHANDLE       *Reserved3,     // not used must be NULL
    LPHANDLE       *Reserved4,     // not used must be NULL
    LPSTR          CodelineSW,
    LPSTR          CodelineHW,
    LPSTR          BarCode,
    LPSTR          CodelinesOptical,
    short          *DocToRead,
    long           *NrPrinted,
    LPVOID         Reserved5,      // not used must be NULL
    LPVOID         Reserved6);

我的 Java 方法是

public int LSGetDocData(
    short hConnect, 
    int hWnd, 
    long[] NrDoc, 
    String FilenameFront, 
    String FilenameBack, 
    String Reserved1, 
    String Reserved2, 
    int[] FrontImage, 
    int[] RearImage,
    int[] FrontImage2, 
    int[] RearImage2, 
    StringBuffer CodelineSW, 
    StringBuffer CodelineHW, 
    StringBuffer Barcode, 
    StringBuffer CodelinesOptical, 
    short[] DocToRead, 
    long[] NrPrinted,
    int Reserved5,
    int Reserved6);

public int lSGetDocData(long[] nrDoc, int[] frontImage, int[] rearImage, StringBuffer micrHW, StringBuffer barcode, StringBuffer micrSW, StringBuffer codeLineOptical) {    
        return LsApi.call.LSGetDocData(hConnect[0], hWnd, 
            nrDoc, "imageF", "ImageR", null, null, 
            frontImage, rearImage, null, null,
            micrSW, micrHW, barcode, codeLineOptical,
            new short[0], new long[0], 0, 0);
}

错误是

Exception in thread "StartCapture" java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokeInt(Native Method)
    at com.sun.jna.Function.invoke(Function.java:426)
    at com.sun.jna.Function.invoke(Function.java:361)
    at com.sun.jna.Library$Handler.invoke(Library.java:265)
    at com.sun.proxy.$Proxy2.LSGetDocData(Unknown Source)

此代码使用 IBM Java 1.6 32 位完美运行……但我们想使用 Oracle Java 1.8 32 位,但出现此错误。

您的类型映射不正确,并且 IBM JDK 可能以与 Oracle 不同的方式处理某些对象(数组、 StringBuffer )的内存指针,从而使这些不正确的映射看起来有效。

一些具体的注意事项:

  • Java 中的long是 64 位,但 C 中的long可以是 32 位或 64 位。您声明您使用的是 32 位 JRE,但不是操作系统位数。 NativeLong可以处理这种差异。
  • HWND在 JNA 中映射,扩展了指针大小的HANDLE 在 32 位系统上, int有效,但您应该使用HWND以实现可移植性。
  • 类似地, LPHANDLE被映射到HANDLEByReference ,一个指向指针大小值的指针。
  • JNA 处理String到 C 字符串的映射,但我不确定StringBuffer 这可能是问题的根源。
  • JNA 不能很好地处理 0 大小的数组。 我怀疑new short[0]new long[0]可能会导致问题,因为您正在定义一个指向空分配的指针。 本机代码是否尝试在这里写一些东西?

总之,在 32 位(或 Windows 的任何位)上, long *映射是错误的,或者在 64 位上, HWNDLPHANDLE映射可能是错误的(取决于指针大小)。 StringBuffer映射可能是可疑的。 并且无法写入 0 大小的数组(因此可能null是合适的)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM