Java调用C++库

问题

https://gist.github.com/santa4nt/4a8fd626335e36c94356
MAC电脑,使用这里的例子,指定好JAVA_INC路径之后,执行脚本报错

  • 报错
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at HelloJNI.(HelloJNI.java:4)

解决

makerun.sh 脚本中生成的 libhello.so 改成 libhello.dylib 即可

原因

一层一层分析

  • 1 . java引用的动态库 libname hello
public class HelloJNI {
    static {
        System.loadLibrary("hello"); 
    }
......
    1. c++生成的动态库 libhello.so
g++ -std=c++11 -shared -fPIC -I$JAVA_INC -I$JAVA_INC/linux HelloJNIImpl.cpp -o libhello.so
    1. 运行java时指定的 java.library.path=.
java -Djava.library.path=. HelloJNI
    1. 报错no hello in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at HelloJNI.(HelloJNI.java:4)
  1. 很显然,问题是没有在 java.library.path 的路径中 找到 libname 为 hello 的动态库,我们在代码里打印一下 java.library.path 和 实际匹配的 libname,发现path ok,libname 为 libhello.dylib,并非libhello.so;
    查看jdk源码发现,jdk对Windows、Mac、Linux操作系统中的 libname 处理各不相同,以前只关注到了 Windows 和 Linux 的区别。
打印变量
public class HelloJNI {
    static {
        System.out.println(System.getProperty("java.library.path"));
        System.out.println(System.mapLibraryName("hello"));
        System.loadLibrary("hello"); 
    }
......
输出结果
.
libhello.dylib
jdk源码
                // Set the lib prefix and suffix based on the OS
                if (osName.startsWith("Windows")) {
                    libPrefix = "";
                    libSuffix = ".dll";
                } else if (osName.startsWith("Mac")) {
                    libPrefix = "lib";
                    libSuffix = ".dylib";
                } else if (osName.startsWith("Linux")) {
                    libPrefix = "lib";
                    libSuffix = ".so";
                }

你可能感兴趣的:(Java调用C++库)