Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 来自JNA和DLL的无效内存访问错误_Java_Dll_Jna - Fatal编程技术网

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

Java 来自JNA和DLL的无效内存访问错误,java,dll,jna,Java,Dll,Jna,我在使用JNA和从LabVIEW创建的DLL文件时遇到问题。当我不用这条线路时,我可以调用它,第一条: FileWriter writer = new FileWriter(FirstPath); BufferedWriter writing = new BufferedWriter(writer); writing.write("Here goes my strings"); writing.close(); 在此之后,DLL类如下所示: DLLClas

我在使用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方法再次调用它?我试过了,但什么也没用。有人能帮我吗?我将非常感激

注意:这是我的DLL类:

  public interface DLLClass extends Library{

  public int myMethodInsideDLLClass(String 
  FirstPath, String SecondPath, String ThirdPath);
  }
扩展库来自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)
如果查看,您将看到它正在调用
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
这一行:

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

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

欢迎来到StackOverflow。请向我们展示方法
dll.myMethodInsideDLLClass()
的映射,特别是您为参数指定的类型。我添加了它。应该就这些了。JNA可能需要知道正确的字符编码,才能将
字符串
正确映射到适当的本机映射。尝试将
w32apoptions.DEFAULT\u OPTIONS
添加到DLL加载语句。我的加载语句?我很抱歉。DLLClass dll=(DLLClass)Native.loadLibrary(“DLLFile”,DLLClass.class,W32APIOptions.DEFAULT_OPTIONS);像这样的?我不知道。对不起,是的,就是这样。我在下面的答案中给出了更详细的回答。我正在实施。希望一切顺利。Lolgots出现此错误:线程“AWT-EventQueue-0”java.lang中出现异常。错误:com.sun.jna.Native.getWideString(本机方法)处的com.sun.jna.Pointer.getWideString(Pointer.java:659)的内存访问无效。
字符串
可能不是正确的映射。原始API中该方法的定义是什么?您是指原始的DllFile.h?是查尔。我想是char还是char*?它是定义一个固定长度的数组还是要求你传递一个缓冲区?啊,不错的选择。或者只需从源代码中复制函数映射器行,以便
StdCallLibrary
…获得此错误。-\u-。线程“AWT-EventQueue-0”java.lang.Error中出现异常:com.sun.jna.Native.getStringBytes(本机方法)处的com.sun.jna.Native.getString(Native.java:2224)处的内存访问无效。我尝试了所有我能想到的方法,但没有任何效果。我担心AWT的使用可能会使事情复杂化。尝试将代码移动到尽可能小的独立(控制台)应用程序中,看看问题是否仍然存在。