我应该如何加载 JNI 的本机库以避免不满意的LinkError?

2022-09-02 19:21:32

我想在Ubuntu 8.10上使用JNI,使用Eclipse和gcc(如果有口味的话,是Ubuntu的标准版本)。

我似乎无法加载我的库,尽管make文件成功创建了它。

主要的 Java 类如下所示:

class Hello {
    public native void sayHello();

    static {
        System.loadLibrary("hello.so");
    }

    public static void main(String[] args) {
        Hello h = new Hello();
        h.sayHello();
    }
}

我的制作文件就是这样;

    all : hello.so

hello.so : Hello.o
    gcc -shared -o hello.so Hello.o

Hello.o : Hello.c Hello.h
    gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -c Hello.c -o Hello.o

Hello.h : Hello.class
    javah -jni Hello

clean :
    -del Hello.h
    -del Hello.o

其余的代码(Hello.c)看起来像人们会想到的。

我得到的错误如下;

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello.so in java.library.path

如果我使用显式路径:

System.loadLibrary("/home/gavin/Work/workspace/JNI/hello.so");

然后它有效,但如果可能的话,我宁愿不使用显式路径。


答案 1

根据Pax,您应该将库路径设置为Java应该查找库的位置。您的库名称应为 libhello.so。然后,加载库的调用应为:

System.loadLibrary("hello");

Linux 库由约定 libname.so 引用,并根据该名称加载。这是来自SWIG文档中的Java中动态链接问题的链接,尽管您没有使用SWIG,但本节仍然相关。


答案 2

您呼叫不正确。该方法采用库名称,例如“hello”,并尝试加载相应的共享对象。在Unix上,它将尝试加载“libhello.so”,在Windows上,它将尝试加载“hello.dll”。它将期望在 中找到该文件。System.loadLibrary()loadLibraryjava.library.path

您可能打算调用的方法是采用完全限定的文件名并加载它。此方法应采用 as 参数,但需要字符串。如果使用 ,则必须手动处理本地命名约定,但不必依赖 进行设置。System.load()Fileloadjava.library.path


推荐