当前位置: 首页 > 知识库问答 >
问题:

JNI:未满足链接错误:找不到依赖库

吕高雅
2023-03-14

我试图编写一个简单的Java程序,通过JNI调用C函数来打印“Hello World”。一切编译都没有错误,但当我运行程序时,我得到一个“UnsatisfiedLinkError:找不到依赖库”。

根据Dependency Walker和dumpbin的说法,唯一的依赖项是“kernel32.dll”,在C:\Windows\System32及其依赖项中,也在System32中。

使命感

    System.loadLibrary("Kernel32");

返回时没有错误,但正在加载Hello。包含打印函数的dll仍会引发错误。

有人知道是什么引起的吗?

编辑:

Dependency Walker确实给出了两个警告/错误:

-错误:由于隐式依赖模块中缺少导出函数,至少有一个模块有未解析的导入。

-错误:发现不同CPU类型的模块。

编辑:

这里有一些更详细的信息:我正在运行64位Windows 7,并编译我的。带有cl的dll(Visual Studio 2010)。

我的Java代码你好。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
        }
    }

我可以毫无错误地编译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

我在Hello中实现了header。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;
    }

C代码是用cl(尽管我也尝试过tcc)编译成Hello的。dll,它存储在与java相同的目录中。班

共有3个答案

柯琛
2023-03-14

你需要

  • 将DLL放入windows\system32\文件夹
  • 指定java。图书馆命令行中的路径
孟沛
2023-03-14

我试图让JNI为学校的最终项目工作,但在一个月的头疼之后,我最终找到了替代方案。试试JavaNative Access。它允许您从Windows(. dll)和Linux(. so)上的任何共享库调用任何C函数,它甚至为一些Win32函数提供了方便方法。将您的本机代码编译到共享库中,然后使用JNA动态链接到库并调用您的函数。它说它比JNI慢得多,这是有道理的,因为所有内容都是动态加载的,但我没有注意到性能受到影响。

为了弄清楚C编译器是如何损坏函数名的–将strlen变成_strlen@4或其他什么–我建议使用DLL Export Viewer(下载链接位于底部附近)。我不知道Linux是否有类似的工具。

陶刚豪
2023-03-14

看起来我的问题是64位系统和java安装以及32位C编译器的结合。

默认情况下,Visual C编译器生成32位应用程序,这在由64位java加载时会导致错误。我用Windows SDK 7.1 64位编译器编译了我的应用程序,它运行时没有出现错误,并且删除了Dependency Walker中的警告。

 类似资料:
  • 我试图从java调用一个使用C样式字符串的C函数。当我使用C风格的字符串时,程序执行得很好,但正如我声明std::string时,不知何故,它再也找不到依赖库了。我在eclipse环境中检查了includes文件夹,它确实包含 这是我的本地文件: 这段代码可以很好地从java编译并运行良好,但只要我尝试使用std::string版本(注释),代码就会编译并创建动态库,但在运行java代码时,我会遇

  • 我正在从事一个使用JNI的Java项目。JNI调用我自己编写的自定义库,比如mylib。这取决于第三方库libsndfile-1。dll。 当我运行我的程序时,它会崩溃 我搜索了这个网站(和其他网站),并尝试了一些修复: > 我修复了mylib中的方法名称。dll,如此处所建议。方法名称不知怎么被编译器弄乱了,但我添加了链接器标志,dll方法名称现在与jni头文件中的名称完全匹配。 我将所有这些D

  • 我有一个JNI dll以及我在带有eclipse的机器上创建的jar文件。 我正在尝试将其部署到另一台机器,但无法通过异常 我有另一个打印java.library.path的程序,我已经验证了这个dll所依赖的dll以及这个dll在java.library.path. 我已经阅读了他们应该在当前目录中的帖子,但这不起作用。 我读过他们应该去jre/bin的帖子,得到了同样的结果。 任何帮助都将不胜

  • 我正在尝试弄清楚如何将我的本机库集成到android代码中。我创建了一个简单的C函数,它在设备上运行代码时运行良好。但是我目前的目标是让它在单元测试环境(jUnit)中工作,我面临着问题: 因此,在单元测试env不工作,我将其保存到系统中。load(“/full/path/to/lib.so”),但现在此行引发异常: java.lang.不满意的链接错误:app\build\中介\cmake\de

  • 为什么我会得到不满意的链接错误? 细节如下: 本机方法的原型及其在我的Java代码中的调用是这样的: 私有本机long sampleFunction(long[][]twoDimArray,long number); p.SampleFunction(twoDimArray,number); 本机方法在VC++代码中的原型是这样的: JNIEXPORT jlong JNICALL Java_MyC

  • 我正在Eclipse上从事一个Java项目,该项目通过JNI使用C OpenCV库。一些图像处理算法是在本机端用OpenCV实现的,我希望使用JNI从java使用它们。 我构建了一个C DLL项目来链接到Java,这导致了一个文件。我使用GCC 6.3编译器编译了OpenCV,并在Eclipse CDT上使用相同的GCC 6.3编译器编译了C代码(以及MinGW链接器)。我还使用Dependenc