繁体   English   中英

jna.loadLibrary 找不到本机库文件

[英]jna.loadLibrary cannot find native library file

我用本机库包装器创建了自己的 jar。 生成的 jar 的结构是:

library.jar
 |- com (there are my .java classes)
 |- libs (there is the native - libmylib.so)
 |- META-INF

我按如下方式加载本机库:

MyLibClass instance = (MyLibClass) Native.loadLibrary("mylib", MyLibClass.class);

现在我想在其他项目中添加这个库并使用它。 但是当我创建 MyLibClass 的一个实例时,我收到一个错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'mylib':
libmylib.so: cannot open shared object file: No such file or directory

我应该如何解决这个问题?

正如JNA 入门页面所述,

使您的目标库可用于您的 Java 程序。 做这件事有很多种方法:

  • 首选方法是将jna.library.path系统属性设置为目标库的路径。 此属性类似于java.library.path ,但仅适用于 JNA 加载的库。
  • 在启动 VM 之前更改适当的库访问环境变量。 这是PATH在Windows上, LD_LIBRARY_PATH在Linux和DYLD_LIBRARY_PATH在OSX。
  • 使您的本机库在您的类路径上可用,在路径{OS}-{ARCH}/{LIBRARY} ,其中{OS}-{ARCH}是 JNA 的本机库规范前缀(例如win32-x86linux-amd64darwin )。 如果资源在 jar 文件中,它将在加载时自动提取。

我已经使用静态 Loader 类完成了该操作,如下所示:

static class Loader {

    private Loader() {
    }

    static String getNative() {
        InputStream in = null;
        FileOutputStream fos = null;
        File fileOut = null;
        System.setProperty("jna.library.path",
                System.getProperty("java.io.tmpdir"));

        in = Loader.class.getResourceAsStream(
                        "/libs/libmylib.so");

        if (in != null) {
            try {
                fileOut = File.createTempFile("mylib", ".so");
                fileOut.deleteOnExit();

                fos = new FileOutputStream(fileOut);

                int count;
                byte[] buf = new byte[1024];

                while ((count = in.read(buf, 0, buf.length)) > 0) {
                    fos.write(buf, 0, count);
                }

            } catch (IOException ex) {
                throw new Error("Failed to create temporary file: " + ex);
            } finally {
                try {
                    in.close();
                } catch (IOException ex) {
                }

                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException ex) {
                    }
                }

                return fileOut.getAbsolutePath();
            }
        } else {
            throw new Error("Couldn't open native library file");
        }
    }
}

在那里我从资源加载库文件并将其内容复制到临时目录。 正如您在这样做之前所看到的,我将 jna.library.path 设置为临时文件夹,因此 JNA 将在那里搜索库。

此外,我正在加载库,如下所示:

MyLibClass instance = (MyLibClass) Native.loadLibrary(Loader.getNative(), MyLibClass.class);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM