在加载JNI库时,如何使用实际库名称进行映射

Onk*_*nki 4 java dll java-native-interface native shared-libraries

我们使用加载任何本机库

System.loadLibrary("hello")
Run Code Online (Sandbox Code Playgroud)

现在我开始知道这个库名称是指基于unix的系统的windowslibhello.so的hello.dll.

那么这些平台相关变化发生在哪里?

JRE是这样做的吗?

wer*_*ero 10

TL;博士

依赖于平台的库名称是使用Java虚拟机的本机方法构建的.实际的算法只是在名称前面添加/附加平台特定的前缀/后缀:

  • Windows:"hello"- >"hello.dll"
  • Linux/Solaris上: "hello" "libhello.so"
  • Mac:"hello"- >"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)
Run Code Online (Sandbox Code Playgroud)

着名的System.loadLibrary实际上叫Runtime.loadLibrary哪个电话ClassLoader.loadLibrary.最后,这些方法的实现调用以下本机方法,将给定的库名称转换为特定于平台的名称:

native java.lang.System.mapLibraryName(String name)
native java.lang.ClassLoader$NativeLibrary.findBuiltinLib(String name) 
Run Code Online (Sandbox Code Playgroud)

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

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

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