java JNI:UnsatisfiedLinkError:找不到依赖库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12127769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JNI: UnsatisfiedLinkError: Can't find dependent libraries
提问by Alden
I'm trying to write a simple Java program that calls a C function via JNI to print "Hello World". Everything compiles with no errors, but when I run the program I get an "UnsatisfiedLinkError: Can't find dependent libraries".
我正在尝试编写一个简单的 Java 程序,该程序通过 JNI 调用 C 函数来打印“Hello World”。一切都编译没有错误,但是当我运行程序时,我得到一个“UnsatisfiedLinkError:找不到依赖库”。
According to Dependency Walker and dumpbin, the only dependency is "kernel32.dll", in C:\Windows\System32 and its dependencies, also in System32.
根据 Dependency Walker 和 dumpbin,唯一的依赖项是 C:\Windows\System32 中的“kernel32.dll”及其依赖项,也在 System32 中。
Calling
打电话
System.loadLibrary("Kernel32");
returns with no error, but loading the Hello.dll that contains the printing function still throws an error.
没有错误返回,但加载包含打印功能的 Hello.dll 仍然会引发错误。
Does anyone know what could be causing this?
有谁知道是什么原因造成的?
EDIT:
编辑:
Dependency Walker does give two warnings/errors:
Dependency Walker 确实给出了两个警告/错误:
-Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
- 错误:由于隐式依赖模块中缺少导出函数,至少有一个模块具有未解析的导入。
-Error: Modules with different CPU types were found.
-错误:找到了具有不同 CPU 类型的模块。
EDIT:
编辑:
Here's some more details: I'm running Windows 7 64-bit, and compiling my .dll with cl (Visual Studio 2010).
以下是更多详细信息:我正在运行 Windows 7 64 位,并使用 cl (Visual Studio 2010) 编译我的 .dll。
My Java code Hello.java:
我的 Java 代码 Hello.java:
public class Hello
{
public static native void hello();
public static void main(String[] args)
{
hello();
}
static
{
// Extra dependencies load with no error
System.loadLibrary("NTDLL");
System.loadLibrary("KERNELBASE");
System.loadLibrary("KERNEL32");
System.loadLibrary("Hello"); // Throws UnsatisfiedLinkError
}
}
I can compile the java file with no error, and use javah -jni to generate a C header Hello.h:
我可以毫无错误地编译java文件,并使用javah -jni生成一个C头文件Hello.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Hello_hello
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
I implement the header in Hello.c:
我在 Hello.c 中实现了头文件:
#include <stdio.h>
#include <jni.h>
#include "Hello.h"
#pragma comment(linker, "/EXPORT:Java_Hello_hello=_Java_Hello_hello@8")
JNIEXPORT void JNICALL
Java_Hello_hello(JNIEnv* env, jclass class)
{
printf("Hello World\n");
return;
}
The C code is compiled with cl (though I have also tried tcc) into Hello.dll, which is stored in the same directory as the java .class
C代码用cl(虽然我也试过tcc)编译成Hello.dll,和java.class存放在同一个目录下
采纳答案by Alden
It looks like my problem was the combination of a 64-bit system and java installation and 32-bit C compiler.
看起来我的问题是 64 位系统和 java 安装以及 32 位 C 编译器的组合。
By default, the Visual C++ cl
compiler generates 32-bit applications, and this caused an error when loaded by 64-bit java. I compiled my application with the Windows SDK 7.1 64-bit compiler, and it ran with no error, as well as removing the warnings in Dependency Walker.
默认情况下,Visual C++cl
编译器生成 32 位应用程序,这会导致在由 64 位 java 加载时出错。我使用 Windows SDK 7.1 64 位编译器编译了我的应用程序,它运行没有错误,并且删除了 Dependency Walker 中的警告。
回答by nuju
I tried getting JNI to work for a final project for school and ended up looking for alternatives after a month of head-banging. Try Java Native Accessinstead. It lets you call any C function from any shared library on Windows (.dll) and Linux (.so), and it even has convenience methods for some Win32 functions. Compile your native code into a shared library, then use JNA to dynamically link to the library and call your functions. It says it's significantly slower than JNI, which makes sense because everything's dynamically loaded, but i noticed no performance hits.
我尝试让 JNI 为学校的最终项目工作,并在一个月的头疼之后最终寻找替代方案。请尝试使用Java Native Access。它允许您从 Windows (.dll) 和 Linux (.so) 上的任何共享库调用任何 C 函数,它甚至为某些 Win32 函数提供方便的方法。将您的本机代码编译到共享库中,然后使用 JNA 动态链接到库并调用您的函数。它说它比 JNI 慢得多,这是有道理的,因为一切都是动态加载的,但我注意到没有性能下降。
For figuring out how the C compilers mangle your function names – turning strlen
into _strlen@4
or something – i recommend DLL Export Viewer(the download link is near the bottom). I don't know if Linux has a similar tool.
为了弄清楚 C 编译器如何修改你的函数名称——strlen
变成_strlen@4
什么——我推荐DLL 导出查看器(下载链接在底部附近)。不知道Linux有没有类似的工具。
回答by jdevelop
you will need to either
你需要要么
- put your DLL to the windows\system32\ folder
- specify java.library.path in command-line
- 将你的 DLL 放到 windows\system32\ 文件夹中
- 在命令行中指定 java.library.path