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

问题描述 投票:1回答:2

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

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

此后,DLL类跟随为:

   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);
  }

扩展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)
java dll jna
2个回答
0
投票

您的堆栈跟踪为问题的根源提供了强有力的提示。

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

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

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

getWideString()

这是使用WinAPI方法的标准方法。从技术上讲,如果您的方法不属于WinAPI,则应该使用该模板作为模板来定义自己的类型映射器。


0
投票

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

替换此行:

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

用此行:

public interface DLLClass extends Library

我想到的另一个潜在问题是,您可能使用的是Java的较新版本,但是您的JNA版本过旧,或者您的库“ DLLFile”版本旧了,并且它不知道内部Java字符串的表示形式在最近的Java版本中已更改,以创建时使用的任何编码方式存储字节,而不是始终使用UTF16。但这确实是在吸管。

© www.soinside.com 2019 - 2024. All rights reserved.