System.loadLibrary()的使用方法汇总 .

本文详细介绍了在Java中通过System.loadLibrary及System.load方法调用DLL文件的具体步骤,并对比了这两种方法的区别。同时,还讨论了如何处理DLL依赖的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当使用System.loadLibrary()调用 Dll,两种方法:

1.设定环境变量。

比如:所编辑的Dll在目录“D:/cppProjects/nativecode/release”内,将这个路径复制添加到电脑的环境变量中的path变量内即可。

2.设定项目属性。(开发推荐)

右击项目名|选择属性properties|在左边列表内选择“Java Build Path”|在右边选项卡用选择“source”|点开项目名前的“+”号,选择“Native library location”,“Edit”选择上面“D:/cppProjects/nativecode/release”路径。(当然如果将dll拷贝到workspace下也可以用相对路径。也可右击“src”设定其properties内Native Library项。)





System.load 和 System.loadLibrary详解

1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。

2.System.load 参数为库文件的绝对路径,可以是任意路径。
例如你可以这样载入一个windows平台下JNI库文件:
System.load("C://Documents and Settings//TestJNI.dll");。

3. System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
例如你可以这样载入一个windows平台下JNI库文件
System. loadLibrary ("TestJNI");

这里,TestJNI.dll 必须是在java.library.path这一jvm变量所指向的路径中。
可以通过如下方法来获得该变量的值:
System.getProperty("java.library.path");
默认情况下,在Windows平台下,该值包含如下位置:
1)和jre相关的一些目录
2)程序当前目录
3)Windows目录
4)系统目录(system32)
5)系统环境变量path指定目录

4.如果你要载入的库文件静态链接到其它动态链接库,例如TestJNI.dll 静态链接到dependency.dll, 那么你必须注意:
1)如果你选择
System.load("C://Documents and Settings// TestJNI.dll");
那么即使你把dependency.dll同样放在C://Documents and Settings//下,load还是会因为找不到依赖的dll而失败。因为jvm在载入TestJNI.dll会先去载入TestJNI.dll所依赖的库文件dependency.dll,而dependency.dll并不位于java.library.path所指定的目录下,所以jvm找不到dependency.dll。
你有两个方法解决这个问题:一是把C://Documents and Settings//加入到java.library.path的路径中,例如加入到系统的path中。二是先调用
System.load("C://Documents and Settings// dependency.dll"); 让jvm先载入dependency.dll,然后再调用System.load("C://Documents and Settings// TestJNI.dll");
2)如果你选择
System. loadLibrary ("TestJNI");
那么你只要把dependency.dll放在任何java.library.path包含的路径中即可,当然也包括和TestJNI.dll相同的目录。


转载:

http://blog.youkuaiyun.com/ring0hx/archive/2008/11/06/3242245.aspx

http://blog.youkuaiyun.com/grtwall/archive/2009/03/03/3954328.aspx
### 关于 `System.loadLibrary` 的用法 #### 1. **基本概念** `System.loadLibrary` 是 Java 提供的一个静态方法,用于加载本地库(Native Library)。该方法会自动根据操作系统平台寻找对应的共享库文件,并将其加载到 JVM 中。通常情况下,开发者不需要关心具体的文件路径或扩展名,只需指定库的名字即可。 #### 2. **方法签名** ```java public static void loadLibrary(String libname) ``` - 参数 `libname`: 表示要加载的本地库的名称,不包含前缀(如 `lib`)和后缀(如 `.so`, `.dll`, `.dylib`)[^1]。 #### 3. **工作原理** 当调用 `System.loadLibrary("yourlibrary")` 时,JVM 会在默认的库路径下查找名为 `libyourlibrary.so`(Linux)、`yourlibrary.dll`(Windows)或 `libyourlibrary.dylib`(macOS)的文件,并尝试加载它。如果找不到对应文件,则抛出 `UnsatisfiedLinkError` 异常[^1]。 #### 4. **代码示例** 以下是一个典型的使用案例: ```java public class LoadLibraryExample { // 声明本地方法 public native void nativeMethod(); static { // 加载本地库 try { System.loadLibrary("yourlibrary"); } catch (UnsatisfiedLinkError e) { System.err.println("Failed to load library: " + e.getMessage()); } } public static void main(String[] args) { LoadLibraryExample example = new LoadLibraryExample(); example.nativeMethod(); // 调用本地方法 } } ``` 此代码展示了如何通过 `System.loadLibrary` 加载一个名为 `yourlibrary` 的本地库,并声明了一个本地方法 `nativeMethod()` 进行调用。 #### 5. **常见问题及解决方案** ##### (1)**未找到库文件** 如果运行程序时报错 `UnsatisfiedLinkError`,可能是由于目标库文件不存在于系统的库路径中。解决办法包括: - 将库文件放置在 JVM 默认的库目录中。 - 设置环境变量 `-Djava.library.path=<path_to_library>` 指定自定义路径[^3]。 ##### (2)**跨平台兼容性** 不同操作系统对库文件有不同的命名约定。例如,在 Linux 上为 `lib<name>.so`,而在 Windows 上为 `<name>.dll`。因此,建议开发时遵循统一的标准命名规则。 ##### (3)**重复加载** 多次调用 `System.loadLibrary` 对同一个库不会引发异常,因为 JVM 只允许每个库被加载一次。后续调用会被忽略[^2]。 #### 6. **与 `System.load` 的区别** 虽然两者都可用于加载本地库,但它们的功能有所不同: - `System.loadLibrary` 接受库名字作为参数,由 JVM 自动解析具体路径。 - `System.load` 则需要提供完整的文件路径,适合处理非标准位置的库文件。 #### 7. **高级应用场景** 对于复杂的场景,比如动态获取 SO 文件路径并通过 JNI 层面操作,可以参考如下实现方式: ```java private static final String LIB_NAME = "test-lib"; private void test() { try { BaseDexClassLoader dexPathClassLoader = (BaseDexClassLoader) Binder.class.getClassLoader(); String targetSoAbsolutePath = dexPathClassLoader.findLibrary(LIB_NAME); Log.e("mLogU", "ClassLoader#findLibrary: " + targetSoAbsolutePath); testdlopen(targetSoAbsolutePath); // 动态 dlopen 并执行函数 } catch (Exception e) { Log.e("mLogU", e.toString()); } } private native void testdlopen(String targetSoAbsolutePath); ``` 这段代码演示了如何利用 `BaseDexClassLoader.findLibrary` 查找 SO 文件的具体路径,并传递给 C/C++ 层进行进一步处理[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值