繁体   English   中英

来自 JNA 和 DLL 的无效 memory 访问错误

[英]Invalid memory access error from JNA and DLL

我在使用 JNA 和从 LabVIEW 创建的 DLL 文件时遇到问题。 当我不使用这条线时,我可以调用它,第一条:

    FileWriter writer = new FileWriter(FirstPath);
    BufferedWriter writing = new BufferedWriter(writer);
    writing.write("Here goes my strings");
    writing.close();

在此之后 DLL class 如下:

   DLLClass dll = (DLLClass)Native.loadLibrary("DLLFile",DLLClass.class);
   dll.myMethodInsideDLLClass(FirstPath,SecondPath,ThirdPath);

看起来它正在尝试访问一些随机的 FirstPath,或者我不知道是什么。 它给了我这个错误。

   Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access
   at com.sun.jna.Native.getStringBytes(Native Method)
   at com.sun.jna.Native.getString(Native.java:2224)
   at com.sun.jna.Pointer.getString(Pointer.java:681)
   at com.sun.jna.Function.invokeString(Function.java:667)
   at com.sun.jna.Function.invoke(Function.java:434)
   at com.sun.jna.Function.invoke(Function.java:361)
   at com.sun.jna.Library$Handler.invoke(Library.java:265)
   at com.sun.proxy.$Proxy0.myMethodInsideDLLClass(Unknown Source)

我的意思是我怎么能访问我试图写入的同一个文件,然后在 dll 方法中再次调用它? 我试过了,但没有任何效果。 有人能帮我吗? 我将非常感激!

注意:这是我的 DllClass:

  public interface DLLClass extends Library{

  public int myMethodInsideDLLClass(String 
  FirstPath, String SecondPath, String ThirdPath);
  }

extends Libray 来自 jna.jar。

这是我的 FileDll.h 文件中的内容:

#ifdef __cplusplus
extern "C" {
#endif


int32_t __cdecl myMethodInsideDLLClass(
    char FirstPath[], char SecondPath[], 
    char ThirdPath[]);


MgErr __cdecl LVDLLStatus(char *errStr, int errStrLen, void *module);

void __cdecl SetExcursionFreeExecutionSetting(Bool32 value);

#ifdef __cplusplus
} // extern "C"
#endif

#pragma pack(pop)

您的堆栈跟踪强烈暗示了问题的根源。

at com.sun.jna.Pointer.getString(Pointer.java:681)
at com.sun.jna.Function.invokeString(Function.java:667)

如果您查看invokeString()的 JNA 源代码,您会看到它正在调用getString()方法,假设为 1 字节字符编码 (ASCII)。 但是 Windows 默认使用 2 字节的 Unicode 字符编码,并且此方法需要知道使用宽字符串,因此它会调用getWideString()

这可以通过在加载 DLL 时分配适当的类型映射器来解决。 最简单的方法是添加默认的 Windows 类型映射:

DLLClass dll = (DLLClass) Native.loadLibrary("DLLFile", DLLClass.class,
    W32APIOptions.DEFAULT_OPTIONS);

这是使用 WinAPI 方法执行此操作的标准方法。 从技术上讲,如果您的方法不是 WinAPI 的一部分,您可能应该定义自己的类型映射器,使用该映射器作为模板。

在您尝试了 Daniel 的建议后,如果它不起作用,请尝试以下操作:

替换这一行:

public interface DLLClass extends Library

有了这条线:

public interface DLLClass extends com.sun.jna.win32.StdCallLibrary

我能想到的另一个潜在问题是,您可能使用的是 java 的较新版本,但您的 JNA 版本较旧,或者您的库“DLLFile”版本较旧,并且它不知道java 字符串在最近的 java 版本中发生了变化,将字节存储在创建时使用的任何编码中,而不是始终使用 UTF16。 但这真的是在抓住稻草。

暂无
暂无

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

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