我们使用
加载任何本地库System.loadLibrary("hello")
现在我才知道这个库名指的是hello.dll for windows 和 libhello.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 版本)中找到:
- http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/System.c#l466
- http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/ClassLoader.c#l495
两种方法都实现了相同的算法来构建实际的库名,
前缀 JNI_LIB_PREFIX
并附加后缀 JNI_LIB_SUFFIX
。
最后宏JNI_LIB_PREFIX
和JNI_LIB_SUFFIX
定义在平台相关的包含文件中,即
关于java - 加载 JNI 库时,映射如何与实际库名称发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37203247/