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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:41:44  来源:igfitidea点击:

JNI: UnsatisfiedLinkError: Can't find dependent libraries

javajava-native-interface

提问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++ clcompiler 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 strleninto _strlen@4or 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