【问题标题】:How to load different native libraries(dll, so) based on the system the application is running如何根据应用程序运行的系统加载不同的原生库(dll、so)
【发布时间】:2014-06-11 21:53:46
【问题描述】:

我有一个使用 JNI 调用的本机库。调用本机库在 Linux 中运行良好。

我的问题是,如果我为 Linux 和 Windows 创建一个 .so.dll 文件并将它们添加到项目中,有没有办法根据我的应用程序在调用时运行的操作系统加载正确的库System.LoadLibrary("myLib")?

换句话说,下面的伪代码的正确实现是什么?

if(Windows){
   System.LoadLibrary("myLib.dll");
}else if(Linux){
   System.LoadLibrary("myLib.so");
}

谢谢

【问题讨论】:

    标签: java jvm java-native-interface classloader


    【解决方案1】:

    恰恰相反,在 Windows 上

    System.loadLibrary("myLib");
    

    将加载 myLib.dll,但在 *x 上它相当于

    System.load(path + "/libmyLib.so");
    

    部署和路径管理将取决于平台,但loadLibrary() 是“一次编码,到处运行”。

    【讨论】:

    • System.mapLibraryName() 应与 System.loadLibrary() 结合使用,以解决上述平台命名差异。
    • System.mapLibraryName() 可能有助于处理相对路径,请参阅 example。但在简单的情况下,System.loadLibrary() 就足够了。
    • 感谢您的指点System.mapLibraryName()。如果System.loadLibrary() 无法加载库,我认为它将通过与System.load() 结合来解决我的问题。我将不得不接受@AlexBarker 的回答,因为它显示了更完整的解决方案。
    【解决方案2】:

    有点复杂,这个loadNativeLibrary() method有一个完整的例子。

    几点说明:

    首先尝试 System.loadLibrary(libName) 以便您的库可以外部化。大多数 Linux 软件包都希望这样做。

    您需要在您的 jar 中设置一些拱形和操作系统原生文件存储的方法。该示例使用一些帮助类来规范化拱名称。见NativeSystem

    OS X 上的早期 Java 版本决定用于 JNI 的动态库应该使用 jnilib 扩展,而不是像系统上的所有其他动态库一样使用 dylib。您可能需要解决这个问题。

    确保将本机库解压缩到唯一的文件路径。当您有并发应用程序将您的原始库的不同版本提取到相同的位置和文件名时,它总是很有趣。

    使用 System.load() 而不是 System.loadLibrary() 来加载提取的二进制文件。这样您就不必担心 java.library.path。

    【讨论】:

    • 谢谢。所示示例更完整地说明了如何解决此问题。对于任何试图解决这个问题的人来说,这是一个很好的参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    相关资源
    最近更新 更多