我有一个使用插件的C ++应用程序(它动态加载某些共享的lib文件)。我在理解从Java调用动态加载的本机代码时需要做些什么。
我有使用System.loadLibrary / System.load来“预加载”本机共享对象(“插件”)以便能够调用该本机代码吗?或者我可以只在我的本机代码中加载后从插件中调用RegisterNatives吗?我已经为我的主本机应用程序库调用了System.loadLibrary - 它是后续插件本机库加载了这个问题。
如果我只能调用RegisterNatives,如果我突然决定卸载插件并且JVM尝试调用其中的本机方法会发生什么?
答案 0 :(得分:0)
至少Android VM要求在实例化类时必须“注册”所有本机方法。这就是为什么System.load()
通常在静态构造函数中调用,而不是以后调用。
解决本机方法的两种方法是通过RegisterNatives()
中的JNI_OnLoad()
或通过名称匹配(javah
报告的C导出函数名称)。
您可以在所有已加载的模块中查找RegisterNatives()
的函数指针,或者加载更多模块并从中获取指针。 RegisterNatives()
可能随时被调用,如果你真的想要卸载一些插件,你可以使用UnregisterNatives()
。
引入后者以支持以下流程(伪代码如下):
SwitchPlugin() {
UnregisterNatives();
unloadPlugin(oldHandle);
newHandle = loadPlugin(newPluginName);
RegisterNatives();
}
如果您的应用尝试使用在已卸载的插件中实现的本机方法,或者在使用UnregisterNatives()
注销后,您的应用可能会崩溃。