gpt4 book ai didi

linux - 通过JNI从其他共享库加载依赖的.so

转载 作者:行者123 更新时间:2023-12-03 10:01:36 24 4
gpt4 key购买 nike

我想从其他libb.so调用liba.so的某些功能。
libb.so是动态的,因此该库实现了我在JNI中使用System.loadLibrary(“b”)加载的 native 方法。首先,我使用java.library.path为jni中的.so设置了完整路径,但是当我运行Java程序时,在加载共享库libb.so时,
它给出以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: x/y/z/libb.so: liba.so: cannot open shared object file: No such file or directory.
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
  • 首先我在编译期间使用以下方法将共享库liba.so与其他共享库libb.so链接在一起

    g++ -shared -o libb.so -fPIC b.cc -L/x/y/z -la

    (例如,liba.so的完整路径为/x/y/z)
  • 在JNI中,我实用地设置了java.library.path,它包含liba.so,libb.so的完整路径,然后我习惯于将JNI native 库libb.so加载为

  • (例如libb.so的完整路径是a/b/c和
    liba.so的完整路径是x/y/z。)
    String libpath = "x/y/z" + "a/b/c";
    System.setProperty( "java.library.path", libpath);
    try {
    Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
    fieldSysPath.setAccessible( true );
    fieldSysPath.set( null, null );
    }
    catch (Exception e)
    {
    System.out.println(e);
    }

    //在这里,我能够打印/获取正确的java.library.path。 (两个共享库的路径都正确保存到java.library.path中)
    static {
    System.loadLibrary("b");
    }

    当我的java程序加载此静态块动态库时,出现以下错误:

    线程“主”中的异常java.lang.UnsatisfiedLinkError:x/y/z/liba.so:libb.so:无法打开共享对象文件:没有这样的文件或目录。

    注意:当我在LD_LIBRARY_PATH中设置liba.so的路径时,此工作正常,没有任何错误。但我不想在SHELL中设置LD_LIBRARY_PATH。我只想在程序本身中设置java.library.path或LD_LIBRARY_PATH。

    提前致谢!

    最佳答案

    假设您控制共享对象liba.solibb.so的位置,请使用embedded libb.so set so that it can locate RPATH 编译liba.so共享对象。

    如果两个共享库位于shame目录中,则可以使用:

    g++ -shared -o libb.so -fPIC b.cc -L/x/y/z -la -Wl,-rpath,'$ORIGIN/.'

    ( $ORIGIN本身可以工作,但是我想使用 $ORIGIN/.清楚地表明结果是目录。如果您具有公用 binlib目录树,则始终对可执行文件和共享对象都使用 $ORIGIN/../lib也是IMO的一个好主意。)
    -Wl,-rpath,'$ORIGIN/.将在 RPATH共享对象中设置一个 libb.so,以便运行时链接程序在 libb.so所在的同一目录中搜索。

    关于linux - 通过JNI从其他共享库加载依赖的.so,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54373254/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com