我应该如何为JNI加载本机库以避免UnsatisfiedLinkError?

gav*_*gav 16 c java java-native-interface

我想在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的make文件是这样的;

    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
Run Code Online (Sandbox Code Playgroud)

其余的代码(Hello.c)看起来像人们想的那样.

我得到的错误如下;

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello.so in java.library.path
Run Code Online (Sandbox Code Playgroud)

如果我使用显式路径:

System.loadLibrary("/home/gavin/Work/workspace/JNI/hello.so");
Run Code Online (Sandbox Code Playgroud)

然后它可以工作,但如果可能的话,我宁愿不使用显式路径.

小智 23

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

System.loadLibrary("hello");
Run Code Online (Sandbox Code Playgroud)

Linux库由常规lib 名称 .so 引用,并根据名称加载.以下是SWIG文档中关于Java中动态链接问题的链接,尽管您没有使用SWIG,但本节仍然具有相关性.


Jes*_*erE 15

你打电话System.loadLibrary()不对.该loadLibrary方法采用库名称,例如"hello",并尝试加载相应的共享对象.在Unix上,它将尝试加载"libhello.so",在Windows上它将尝试加载"hello.dll".它将期望找到该文件java.library.path.

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


小智 6

请执行下列操作:

  1. 将您的Java类更改为:

    class Hello {
    
        public native void sayHello();
    
        static {
            System.loadLibrary("hello");
        }
    
        public static void main(String[] args) {
            Hello h = new Hello();
            h.sayHello();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将hello.so重命名为libhello.so: cp hello.so libhello.so或mv hello.so libhello.so

  3. 运行方式: java -Djava.library.path=/home/gavin/Work/workspace/JNI/ Hello


pax*_*blo 5

你用以下的东西运行它吗?

java -Djava.library.path=/home/gavin/Work/workspace/JNI Hello
Run Code Online (Sandbox Code Playgroud)

您需要确保共享对象位于库路径中.