在java中可靠地卸载dll

时间:2010-11-30 15:22:32

标签: java dll java-native-interface

我想在java中卸载一个dll。我已阅读thisthis,但您似乎无法保证dll实际上会在特定时间卸载。这是因为System.gc()只是“请求”垃圾收集器运行。

所以这是情况的分解。我有一个通过JNI提供一些功能的DLL。让我们称之为dll MainDll。 MainDll从调用System.load(“MainDll”)加载。我需要能够在运行中卸载并加载此dll。

是否可以创建另一个dll,其唯一目的是加载和卸载MainDll。让我们称之为dll LoaderDll。然后我可以简单地调用System.load(“LoaderDll”)并使用一些本机函数来加载和卸载MainDll。这样做的原因是,我可以访问本机系统上可以动态加载和卸载dll的函数。这个棘手的部分是,如果从LoaderDll内部加载,我是否仍然可以访问我在MainDll中编写的本机函数。

对不起,如果这是一个令人困惑的问题。这似乎有点难以解释。

由于

5 个答案:

答案 0 :(得分:2)

创建一个执行加载/卸载的包装器DLL。 DLL中还有包装器方法,可以转向并将调用委托给加载的MainDll DLL。这样,您的Java JNI代码只知道单个DLL。它仍然可以请求卸载[LoaderDll :: unload()],它在内部卸载MainDll。

只要当MainDll当前未加载时调用它们时,LoaderDll中的方法/函数可以触发MainDll的加载,这应该有效,假设这是所需的行为,而不是抛出异常/错误。

这方面的一个问题是LoaderDll将始终被加载。

答案 1 :(得分:1)

添加间接级别。

使您的本机方法在LoaderDLL中调用转发例程。转发例程可以使用C工具将调用转发到mainDLL中的代码。

答案 2 :(得分:0)

如果您需要动态加载和卸载代码,请考虑OSGi。这至少在felix中起作用。

在Oracle / Sun的JDK中,System.gc()将触发一个完整的gc(除非它已在命令行中关闭)。它可能只是对其他JVM的暗示。

答案 3 :(得分:0)

根据您的澄清评论,我认为最简单的方法是生成一个新的JVM,其唯一的责任是管理您的DLL。可能会暴露一个RMI接口来访问这些类(尽管简单的流可能就足够了)。

答案 4 :(得分:0)

我还没有遇到过System.gc()没有触发垃圾收集器的情况,尽管它只是一个提示。 本教程实际上帮助我完成了我的工作:Unload Java JNI DLL

相关问题