我想在java中卸载一个dll。我已阅读this和this,但您似乎无法保证dll实际上会在特定时间卸载。这是因为System.gc()只是“请求”垃圾收集器运行。
所以这是情况的分解。我有一个通过JNI提供一些功能的DLL。让我们称之为dll MainDll。 MainDll从调用System.load(“MainDll”)加载。我需要能够在运行中卸载并加载此dll。
是否可以创建另一个dll,其唯一目的是加载和卸载MainDll。让我们称之为dll LoaderDll。然后我可以简单地调用System.load(“LoaderDll”)并使用一些本机函数来加载和卸载MainDll。这样做的原因是,我可以访问本机系统上可以动态加载和卸载dll的函数。这个棘手的部分是,如果从LoaderDll内部加载,我是否仍然可以访问我在MainDll中编写的本机函数。
对不起,如果这是一个令人困惑的问题。这似乎有点难以解释。
由于
答案 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