【发布时间】:2015-08-03 00:25:18
【问题描述】:
我的 Java 代码使用 JNA 加载本机库,如下所示:
69. Print.good("found file: " + libraryPath);
70. if( System.getProperty("os.name").toLowerCase().contains("win") ) {
71. final String search_path = FileFinder.getParentDirPath(libraryPath);
72. NativeLibrary.addSearchPath("libReliableServerNative",
73. search_path );
74. Print.good("Added search path: " + search_path);
75. System.setProperty("java.library.path", search_path);
76. nativeLib = (NativeLib) Native.loadLibrary("libReliableServerNative", CTest.class);
}
我的终端输出,打印行号和库文件位置,如下所示:
++ Thread "main": Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:69)
++ found file: C:\Users\HOLLYWOOD\Documents\NetBeansProjects\ReliableServerMadeUnreliable2\build\classes\libReliableServerNative.dll
++ Thread "main": Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:74)
++ Added search path: C:\Users\HOLLYWOOD\Documents\NetBeansProjects\ReliableServerMadeUnreliable2\build\classes
java.lang.UnsatisfiedLinkError: The specified module could not be found.
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.Native.open(Native.java:1759)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:76)
Exception in thread "main" Java Result: 1
^ 您在我的 Java 代码的第 76 行看到,Native.loadLibrary 抛出了 UnsatisfiedLinkError。 ^
我排除了混淆 32 位和 64 位库的可能性,因为我在 32 位 Windows 机器上用 32 位 Java 编译了本机库和 Java 代码,并指定了“-m32” gcc 的命令行参数,应该输出一个 32 位的 dll。对于本机编译,我使用了 cygwin。
我还排除了找不到库的可能性,因为在这种情况下,我得到的是“java.lang.UnsatisfiedLinkError: UnsatisfiedLinkError: Unable to load library”而不是上面的“java.lang.UnsatisfiedLinkError:找不到指定的模块。”
我认为正在发生的事情是“它无法加载...... dll 缺少一些依赖项。”但是本机库(libReliableServerNative.dll)只不过是一个 C 文件,除了 C 标准库之外没有其他依赖项。
libReliableServerNative 的完整依赖项:
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h> // inet_aton
#include<sys/socket.h> // unix socket
#include <unistd.h>
#include <netinet/in.h>
你知道为什么会这样吗?
* 更新 * 当我将 cygwin1.dll 放入 jna 路径时,不满意的链接错误消失了。
我现在的问题是我没有收到任何错误消息。本机方法永远不会被调用 - 本机代码中不会出现 printf 语句,但程序不会终止或抛出任何异常。调用 nativeLib.myFunction() 后的 java 语句不会被执行。
【问题讨论】:
-
对于第 1 项),这并不能证明或反驳库的位数。要确定您拥有什么,请使用
dumpbin.exe或诸如Dependency Walker dependencywalker.com 之类的实用程序。您没有提到的另一种可能性是,您可能在某个地方潜伏着旧版本的库,而这正是 Java 正在使用的版本。 -
当我加载一个用 cycgwin 编译的 dll 时,它是依赖于一个名为“cygwin.dll”的单独文件,还是包含在 libReliableServerNative.dll 中?
-
我从未在 Windows x86 以外的任何 PC 上编译过这个东西——它是 64 位 dll 文件的可能性几乎为零。此外,我对源代码进行了零更改。只有一个版本存在。
标签: java dll java-native-interface native jna