System.load(String filename)和System.loadLibrary(String libname)的区别

Posted IT·达人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了System.load(String filename)和System.loadLibrary(String libname)的区别相关的知识,希望对你有一定的参考价值。

前言

之前一篇文章在写Native方法的时候,第一个步骤里面有这么一段代码

static
{
  System.load("D:" + File.separator + "Hello.dll");
}

其实JDK提供给用户了两个方法用于载入文件,一个是System.load(String filename)方法,另外一个是System.load(String libname)方法,本文主要写一下这两个方法之间的区别。

 

区别

1、加载的路径不同

System.load(String filename)我们看JDK API的描述是“从作为动态库的本地文件系统中以指定的文件名加载代码文件。文件名参数必须是完整的路径名。”,因此这个方法的参数必须是要加载的文件的完整路径,带文件后缀名。

System.loadLibrary(String libname)我们看JDK API的描述是“加载由libname参数指定的系统库。将库名映射到实际系统库的方法取决于系统”,这里关键问题就是系统库三个字。什么是系统库,做个实验,修改一下static块中的代码,用loadLibrary方法来加载

1
2
3
4
static
{
    System.loadLibrary("Hello");

运行一下,看一下结果

看到报错了,在java.library.path中没有找到Hello,OK,那这样就很简单了,我们知道了系统库指的是java.library.path,用System.getProperty(String key)方法查看一下java.library.path指向的内容

1
2
3
4
public static void main(String[] args)
{
    System.out.println(System.getProperty("java.library.path"));
}

打印的内容太多了,就不放上来了,反正放到任意的一个路径下都可以,注意一下不要带后缀名。至于java.library.path指的是什么,网上很多,就不做复制黏贴的工作了。

2、这个是网上看别人写的才知道的,假如A.dll和B.dll有依赖关系,比如 A.dll静态链接到B.dll,那么如果选择System.load("D:/A.dll"),即使B.dll也放在D:/路径下,load方法还是会 因为找不到依赖的.dll文件而失败。因为Java虚拟机在载入A.dll的时候,发现它依赖于B.dll,那么会先去 java.library.path下载入B.dll,而B.dll并不位于java.library.path下。有两个解决方案:

(1)先System.load("D:/B.dll")再System.load("D:/A.dll")

(2)把A.dll和B.dll都放在java.library.path下,然后调用System.loadLibrary("A")

不过两个dll文件存在依赖关系,A.dll依赖于B.dll,属于别的领域的知识,我也不是很清楚,所以第二点也没有亲身试验过。权当把这个知识点放在这儿,以后万一遇到类似问题了,也有个解决问题的方向。

以上是关于System.load(String filename)和System.loadLibrary(String libname)的区别的主要内容,如果未能解决你的问题,请参考以下文章

System.load 和 System.loadLibrary详解

System.load()与System.loadLibrary()

使用 System.load(dll) 执行 JAVA 应用程序

一文说清linux system load

如何解决java调dll报Unable to load library的错误

如何解决java调dll报Unable to load library的错误