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

Eclipse中的JNI未满足链接错误找不到依赖库

洪祺
2023-03-14

我试图从java调用一个使用C样式字符串的C函数。当我使用C风格的字符串时,程序执行得很好,但正如我声明std::string时,不知何故,它再也找不到依赖库了。我在eclipse环境中检查了includes文件夹,它确实包含

package test_strings;

public class TestString {
    
    static {
        System.load("C:\\Users\\aurok\\eclipse-workspace\\native_cpp\\Debug\\libnative_cpp.dll");
    }
    
    public native String sayHelloC();
    public native String sayHelloCpp();

    public static void main(String[] args) {
        
        TestString test = new TestString();
        
        System.out.println(test.sayHelloC());
        System.out.println(test.sayHelloCpp());

    }

}

这是我的本地文件:

#include "test_strings_TestString.h"
#include<string>
using namespace std;

JNIEXPORT jstring JNICALL Java_test_1strings_TestString_sayHelloC
  (JNIEnv *env, jobject thisObj){

    jstring str = env->NewStringUTF("Hello World C-style !!");
    return str;
}

JNIEXPORT jstring JNICALL Java_test_1strings_TestString_sayHelloCpp
  (JNIEnv *env, jobject thisObj){
    //std::string str = "Hello World C++ style !!";
    //return env->NewStringUTF(str.c_str());
    return env->NewStringUTF("Hello World C++ style !!");
}

这段代码可以很好地从java编译并运行良好,但只要我尝试使用std::string版本(注释),代码就会编译并创建动态库,但在运行java代码时,我会遇到以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\aurok\eclipse-workspace\native_cpp\Debug\libnative_cpp.dll: Can't find dependent libraries
    at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
    at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:383)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169)
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2383)
    at java.base/java.lang.Runtime.load0(Runtime.java:746)
    at java.base/java.lang.System.load(System.java:1857)
    at test_strings.TestString.<clinit>(TestString.java:6)

我已经搜索了各种来源,寻找可能的解释,但没有找到。伙计们,帮帮我!

共有2个答案

樊宏邈
2023-03-14

非常感谢你的回答。我终于想出了一个办法让它发挥作用。我使用lucasg的依赖项工具,发现libgcc\u s\u seh-1。dll和libstdc-6。dll丢失,即使它们存在于MinGW bin中。

因此,我显式地将它们添加到与动态库相同的文件夹中,并将它们加载到java虚拟环境中。这就是java方面现在的样子:

package test_strings;

import java.io.IOException;

public class TestString {
    
    static {
        System.load("C:\\Users\\aurok\\eclipse-workspace\\native_cpp\\Debug\\libwinpthread-1.dll");
        System.load("C:\\Users\\aurok\\eclipse-workspace\\native_cpp\\Debug\\libgcc_s_seh-1.dll");
        System.load("C:\\Users\\aurok\\eclipse-workspace\\native_cpp\\Debug\\libstdc++-6.dll.dll");
        System.load("C:\\Users\\aurok\\eclipse-workspace\\native_cpp\\Debug\\libnative_cpp.dll");
    }
    
    public native String sayHelloC();
    public native String sayHelloCpp();

    public static void main(String[] args) {
        
        TestString test = new TestString();
        
        System.out.println(test.sayHelloC());
        System.out.println(test.sayHelloCpp());

    }

}

注意:DLL的加载顺序很重要。它在任何其他订单中都不起作用。

程祺
2023-03-14

<代码>

但是,根据项目配置为链接到C和C运行时库(静态或动态)的方式,生成的可执行文件可能依赖于也可能不依赖于其他DLL。(例如,对于Microsoft Visual Studio 2019 C编译器,C运行时库DLL为vcruntime140.DLL,C运行时库DLL为msvcp140.DLL)

使用std::string可能会导致您的可执行文件依赖于C运行时库DLL(除了C运行时DLL之外),并且可能与可执行文件不在同一文件夹中(也不在DLL搜索路径中)。

在Windows上,C运行时DLL通常已经在系统范围内可用,但C运行时DLL需要安装(使用Microsoft Visual C可再发行包)或沿可执行文件本身放置在同一文件夹中。

另一种选择是静态链接运行库,这样生成的可执行文件就不会有那些DLL依赖项。但通常,首选动态链接。

请注意,根据您在Eclipse IDE中使用的C编译器(GCC(G)、Clang、MSVC或其他),所需的C运行时DLL将具有不同的文件名。

 类似资料:
  • 我试图编写一个简单的Java程序,通过JNI调用C函数来打印“Hello World”。一切编译都没有错误,但当我运行程序时,我得到一个“UnsatisfiedLinkError:找不到依赖库”。 根据Dependency Walker和dumpbin的说法,唯一的依赖项是“kernel32.dll”,在C:\Windows\System32及其依赖项中,也在System32中。 使命感 返回时没

  • 我正在从事一个使用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