java 加载dll介绍(转)

最近在做的工作要用到本地方法,需要在Java中加载不少动态链接库(以下为方便延用Windows平台下的简写dll,但并不局限于Windows)。刚刚把程序跑通,赶紧把一些心得写出来,mark。也希望对大家的类似工作有所帮助 

首先,应当明确,dll有两类:(1)Java所依赖的dll和,(2)dll所依赖的dll。正是由于第(2)种dll的存在,才导致了java中加载dll的复杂性大大增加,许多说法都是这样的,但我实验的结果却表明似乎没有那么复杂,后面会予以详细阐述。 

其次,Java中加载dll的方式也有两种:(1)通过调用System.loadLibrary(String filename)和,(2)通过调用System.load(String filename)方法。其底层都是通过使用ClassLoader中的loadLibrary(Class fromClass, String name, boolean isAbsolute)方法来实现的,区别仅在于(1)中的filename必须是绝对路径,(2)中的filename只能是dll名,不允许包含文件夹。 

再者,Eclipse是一个相当强大的平台,其提供的BundleClassLoader的强大是一个很重要的原因,对于dll的加载也有自己一套很别致的做法,值得我们采纳。 

根据上面的介绍,分两部分阐述Java中加载dll面临的主要问题和解决途径。 

1. 在一般Java程序中加载dll 

我所做的工作,需要加载的dll如下: 

DigitDll.dll  
DsivsAcct.dll 
DsivsComm.dll 
DsivsTrans.dll 
JBPack.dll 
XCodeDll.dll 
ImageDllCtrl.dll 
yhfiche.dll 
yhocr.dll 
yhbill.dll 
TSealSvrDll.dll 
TImg.dll 
TImage.dll    

直接调用的是TImage中的若干方法,列表中TImage之前的所有其直接或间接依赖的,不仅要把所有的dll load全,更要注意他们之间的依赖关系,被依赖dll一定要先加载,否则就会报错:UnsatisfiedLinkError。故而,首先应理清dll 之间的依赖关系,上面的列表已经是处理过的了。 

接下来是设置JVM的搜索路径,使其能够找到你的dll。JVM的搜索路径由java.library.path系统属性决定,其默认值为系统环境变量中的PATH 内容。因此,可以通过修改PATH变量来达到设置java.library.path属性的目的(改变之后Eclipse需要重新启动),一般的方法是在 PATH中加入dll所在文件夹的绝对路径。另一种方法是在Java命令的参数中加入“-Djava.library.path=dll所在文件夹的绝对路径”来设置(可以用;分开多个路径)。对于Eclipse开发环境上的应用程序,可以通过修改其启动参数,在VM arguments编辑框中加入前述参数。对于打包出来的Eclipse安装包,可编辑其启动目录下的application.ini(假设其启动文件为 application.exe),在-vmargs后加入前述参数来设置java.library.path的值。需要注意的是,一旦JVM已经启动,则无法再修改java.library.path的内容了,也就是说,通过: 

System.setProperty("java.library.path", "c:\mylib"); 

这样的方式是无法达到目的的,因为该属性是只读的。Sun公司的论坛上曾经讨论过如何在代码中修改java.library.path的问题,结论是:不能通过代码修改!如果嫌"java -Djava.library.path=c:\mylib"这样的方式写得太死,也只能是通过shell编程之类的方法对路径进行预处理,以改善其灵活性了。 

如果你的dll是封装在jar包中的,则需要首先将之解压缩到一个临时路径上,然后再将该路径加入到Djava.library.path中,或者干脆将其解压缩到系统路径上。 

2. 在Eclipse平台上加载dll 

上面提到,Java中对本地库路径的设置方式做得太死,这也是我自己的切身体会,但令人感到欣慰的是我们的Eclipse平台的提供了一套比较灵活的做法,通过eclipse提供的BundleClassLoader,你可以将dll封在plugin中,既不需要在使用时解压缩,也不需要额外设置 java.library.path属性,BundleClassLoader会自行到以相对plugin根目录的指定目录下去查找你的dll,这些目录是:ws/win32/, os/win32/x86/, os/win32/, nl/zh/CN/, nl/zh/,见org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader和 org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook。 

我的目录设置是: 
.classpath 
.cvsignore 
.project 
build.properties 
classes 
CVS 
lib 
META-INF 
os 
plugin.xml 
src 

我把所有的dll都放到了os下面的win32目录内,同样可以建立ws/win32等目录用于放置本地库。如此处理之后,不用再修改任何系统变量就可以顺利加载本地库了。 

另外,Eclipse还在MANIFEST文件中提供了Bundle-NativeCode的设置项,也是用于加载本地库的,有待进一步研究 

本文匆匆而就,希望对自己对大家都能有所帮助 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xiaolang85/archive/2008/12/25/3604971.aspx

 

http://dongjiliwu.iteye.com/blog/421726

时间: 2025-01-02 01:16:52

java 加载dll介绍(转)的相关文章

Windows环境下Java加载DLL

  How to Load a Java Native/Dynamic Library (DLL) There are several ways to make it possible for the Java runtime to find and load a dynamic library (DLL) at runtime. I will list them briefly here, followed by examples and further explanation below.

java jni加载dll文件异常

问题描述 java jni加载dll文件异常 Can't load this .dll (machine code=0x101) on a AMD 64-bit platform 解决方案 32位,64位兼容性的问题吧,, 解决方案二: 可能是32位和64位的兼容问题

JAVA加载类库的顺序

加载 JAVA加载库的方法跟它的CLASSLOADER有关,不同的JVM有不同的CLASSLOADER.现介绍J2SDK自带的JVM的加载顺序. 首先,JAVA会跟据系统的参数CLASSPATH,把参数里所包含的JAR(ZIP,目录)加载.只要使用该JVM,不用设置CLASSPATH,程序里用到类就会自动到这里面找到并加载. 其次,在我们运行java.exe 运行某个程序时,也可以加上-classpath(-cp)加上所用到的包.不过这些包只在这次运行会有效,对别的程序运行并没影响. 最后,程序

Lua5.1中加载dll动态链接库的方法

  这篇文章主要介绍了Lua5.1中加载dll动态链接库的方法,本文讲解了加载专门为lua写的扩展dll的方法和加载不是专为lua写的扩展dll的方法,需要的朋友可以参考下 一.加载专门为lua写的扩展dll 使用require或package.loadlib方法,在此不做过多解释. 二.加载不是专为lua写的扩展dll "不是专为lua写的扩展dll"是指:dll中并没有以lua注册函数的方式导出接口,而是以__declspec(dllexport)形式导出的接口.这样就不能使用&q

利用xwizard.exe加载dll

本文讲的是利用xwizard.exe加载dll,在之前的文章介绍了利用Excel.Application object's RegisterXLL()加载dll的技巧.本文继续,介绍最近学习到的一种更为通用的方法--利用xwizard.exe加载dll.  该方法最大的特点是xwizard.exe自带微软签名,在某种程度上说,能够绕过应用程序白名单的拦截. 0x01 简介 本文将要介绍以下内容: · xwizard.exe简介 · 利用思路 · 实际测试 0x02 xwizard.exe简介 应

利用Excel.Application object’s RegisterXLL() method加载dll

本文讲的是利用Excel.Application object's RegisterXLL() method加载dll,Ryan Hanson‏@ryHanson最近分享了一个技巧,利用Excel.Application object's RegisterXLL()能够加载dll.我对其分享的POC作了测试,接着做了扩展,添加功能实现远程下载执行,并且分析该方法相关的利用技巧,详细介绍脚本开发中的细节. 0x01 简介 本文将要介绍如下内容: · POC测试 · 添加功能实现远程下载执行 · 扩

C#中如何动态加载Dll

1.新建测试dll及方法,用vs2010新建winform程序,具体代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace reflect { public

异常-C#调用动态库,无法加载 DLL"xx.dll": 找不到指定的模块。

问题描述 C#调用动态库,无法加载 DLL"xx.dll": 找不到指定的模块. 报错内容:System.DllNotFoundException: 无法加载 DLL"XX.dll": 找不到指定的模块. (异常来自 HRESULT:0x8007007E). 网上的各种方法我都试过了,都是这样 我把目标平台改成x64,报错就变成:System.BadImageFormatException: 试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000

tcl-TCL加载DLL,通过pkg_mkIndex $dllPath **.dll建立索引不成功

问题描述 TCL加载DLL,通过pkg_mkIndex $dllPath **.dll建立索引不成功 set dllPath "C:TesttoolsGTRBINlibexcelpkg" // 设置DLL所在的路径 pkg_mkInde**x _ $dllPath **.dll package require Tclexcelapi (Tclexcelapi是dll包的名字) 正确的结果是索引文件中最后一行代码,如下: package ifneeded Tclcerapi 1.0 [l