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

huangapple go评论90阅读模式
英文:

How can i handle a Java internal memory access using JNA

问题

以下是翻译好的内容:

C代码部分:

  1. extern int APIENTRY LSGetDocData(
  2. short hConnect,
  3. HWND hWnd,
  4. unsigned long *NrDoc,
  5. LPSTR FilenameFront,
  6. LPSTR FilenameBack,
  7. LPSTR Reserved1, // not used must be NULL
  8. LPSTR Reserved2, // not used must be NULL
  9. LPHANDLE *FrontImage,
  10. LPHANDLE *BackImage,
  11. LPHANDLE *Reserved3, // not used must be NULL
  12. LPHANDLE *Reserved4, // not used must be NULL
  13. LPSTR CodelineSW,
  14. LPSTR CodelineHW,
  15. LPSTR BarCode,
  16. LPSTR CodelinesOptical,
  17. short *DocToRead,
  18. long *NrPrinted,
  19. LPVOID Reserved5, // not used must be NULL
  20. LPVOID Reserved6);

Java方法部分:

  1. public int LSGetDocData(
  2. short hConnect,
  3. int hWnd,
  4. long[] NrDoc,
  5. String FilenameFront,
  6. String FilenameBack,
  7. String Reserved1,
  8. String Reserved2,
  9. int[] FrontImage,
  10. int[] RearImage,
  11. int[] FrontImage2,
  12. int[] RearImage2,
  13. StringBuffer CodelineSW,
  14. StringBuffer CodelineHW,
  15. StringBuffer Barcode,
  16. StringBuffer CodelinesOptical,
  17. short[] DocToRead,
  18. long[] NrPrinted,
  19. int Reserved5,
  20. int Reserved6);
  21. public int lSGetDocData(long[] nrDoc, int[] frontImage, int[] rearImage, StringBuffer micrHW, StringBuffer barcode, StringBuffer micrSW, StringBuffer codeLineOptical) {
  22. return LsApi.call.LSGetDocData(hConnect[0], hWnd,
  23. nrDoc, "imageF", "ImageR", null, null,
  24. frontImage, rearImage, null, null,
  25. micrSW, micrHW, barcode, codeLineOptical,
  26. new short[0], new long[0], 0, 0);
  27. }

错误部分:

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

这段代码在使用 IBM Java 1.6 32 位版本时完美运行,但我们想要使用 Oracle Java 1.8 32 位版本,却出现了这个错误。

英文:

the c code is

  1. extern int APIENTRY LSGetDocData(
  2. short hConnect,
  3. HWND hWnd,
  4. unsigned long *NrDoc,
  5. LPSTR FilenameFront,
  6. LPSTR FilenameBack,
  7. LPSTR Reserved1, // not used must be NULL
  8. LPSTR Reserved2, // not used must be NULL
  9. LPHANDLE *FrontImage,
  10. LPHANDLE *BackImage,
  11. LPHANDLE *Reserved3, // not used must be NULL
  12. LPHANDLE *Reserved4, // not used must be NULL
  13. LPSTR CodelineSW,
  14. LPSTR CodelineHW,
  15. LPSTR BarCode,
  16. LPSTR CodelinesOptical,
  17. short *DocToRead,
  18. long *NrPrinted,
  19. LPVOID Reserved5, // not used must be NULL
  20. LPVOID Reserved6);

and my Java method is

  1. public int LSGetDocData(
  2. short hConnect,
  3. int hWnd,
  4. long[] NrDoc,
  5. String FilenameFront,
  6. String FilenameBack,
  7. String Reserved1,
  8. String Reserved2,
  9. int[] FrontImage,
  10. int[] RearImage,
  11. int[] FrontImage2,
  12. int[] RearImage2,
  13. StringBuffer CodelineSW,
  14. StringBuffer CodelineHW,
  15. StringBuffer Barcode,
  16. StringBuffer CodelinesOptical,
  17. short[] DocToRead,
  18. long[] NrPrinted,
  19. int Reserved5,
  20. int Reserved6);
  21. public int lSGetDocData(long[] nrDoc, int[] frontImage, int[] rearImage, StringBuffer micrHW, StringBuffer barcode, StringBuffer micrSW, StringBuffer codeLineOptical) {
  22. return LsApi.call.LSGetDocData(hConnect[0], hWnd,
  23. nrDoc, "imageF", "ImageR", null, null,
  24. frontImage, rearImage, null, null,
  25. micrSW, micrHW, barcode, codeLineOptical,
  26. new short[0], new long[0], 0, 0);
  27. }

the error is

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

This code works perfectly using IBM Java 1.6 32 bits... but we want to use Oracle Java 1.8 32 bits and we get this error.

答案1

得分: 1

您的类型映射不正确,IBM JDK 可能以与 Oracle 不同的方式处理某些对象(数组、StringBuffer)的内存指针,使这些不正确的映射似乎能够工作。

一些具体的注意事项:

  • 在Java中,long 是64位的,但在C中,long 可能是32位或64位。您提到您正在使用32位的JRE,但没有提到操作系统的位数。NativeLong 可以处理这种差异。
  • HWND 在JNA中被映射为扩展HANDLE,而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 是合适的)。

英文:

Your type mappings are not correct, and it is possible that the IBM JDK handled pointers to memory for some objects (arrays, StringBuffers) in a different manner than Oracle, permitting these incorrect mappings to appear to work.

Some specific notes:

  • long in Java is 64 bits, but long can be 32-bits or 64-bits in C. You state you're using a 32-bit JRE but not what the operating system bitness is. NativeLong can handle this difference.
  • HWND is mapped in JNA, extending HANDLE, which is pointer-sized. On 32-bit systems, int works, but you should use HWND for portability.
  • similarly, LPHANDLE is mapped to HANDLEByReference, a pointer to a pointer-sized value.
  • JNA Handles the mapping of String to C Strings, but I'm not sure about StringBuffer. This could be a source of the problem.
  • JNA does not handle 0-sized arrays well. I suspect the new short[0] or new long[0] may be causing problems, as you're defining a pointer to an empty allocation. Does the native code attempt to write something here?

In summary, on 32-bit (or any bitness of Windows) the long * mapping is wrong, or on 64-bit the HWND and LPHANDLE mappings are probably wrong (depending on pointer size). The StringBuffer mappings might be suspect. And 0-size arrays cannot be written to (so perhaps null is appropriate there).

huangapple
  • 本文由 发表于 2020年8月29日 04:18:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63640391.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定