java - 加载 JNI 库时,映射如何与实际库名称发生

标签 java dll java-native-interface shared-libraries native

我们使用

加载任何本地库
System.loadLibrary("hello")

现在我才知道这个库名指的是hello.dll for windowslibhello.so 用于基于 unix 的系统。

那么这些依赖于平台的变化发生在哪里呢?

JRE 是这样做的吗?

最佳答案

tl;dr

依赖于平台的库名称是在 Java 虚拟机的 native 方法中构建的。 实际的算法只是简单地在名称前添加/追加平台特定的前缀/后缀:

  • Windows: "hello" -> "hello.dll"
  • Linux/Solaris:“你好” “libhello.so”
  • Mac:“你好” -> “libhello.dylib”

长版:

有几个 JDK Java 方法可以处理加载库和/或库名称:

java.lang.System.loadLibrary(String name)
java.lang.System.mapLibraryName(String name)
java.lang.Runtime.loadLibrary(String name) 
java.lang.ClassLoader.loadLibrary(String name)

著名的System.loadLibrary其实调用的是Runtime.loadLibrary,后者调用的是ClassLoader.loadLibrary。 最后,这些方法的实现调用以下本地方法来翻译给定的库名称 进入平台特定名称:

native java.lang.System.mapLibraryName(String name)
native java.lang.ClassLoader$NativeLibrary.findBuiltinLib(String name) 

这些本地方法的实现可以在(链接到 OpenJDK 版本)中找到:

两种方法都实现了相同的算法来构建实际的库名, 前缀 JNI_LIB_PREFIX 并附加后缀 JNI_LIB_SUFFIX

最后宏JNI_LIB_PREFIXJNI_LIB_SUFFIX定义在平台相关的包含文件中,即

关于java - 加载 JNI 库时,映射如何与实际库名称发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37203247/

相关文章:

java - 在 java.util.Collection 和 java.lang.Iterable 中声明的方法 iterator(),它的超接口(interface)?

windows - 如果它的导出没有改变,我是否需要针对 dll 进行重建?

c++ - 启动使用附加库的可执行程序

c# - 使用可变数量的功能

java - 进行 JNI 调用时出现 Unsatisfied Link 错误

c++ - JNI : C++ platform in VS2010

java - 制作实例化列表时 <?> 是什么类型?

java - 使用 Tesseract (Tess4J) 识别彩色文本

c++ - Android中的Jni层

java - 如何修复 jasperReports 上 barcode4j-2.1.jar 中的 java.lang.NoClassDefFoundError?