在Android NDK上将全局变量初始化为零

时间:2011-06-16 16:41:58

标签: android android-ndk

我正在使用普通C和最新的Android NDK开发应用程序。我注意到* .so永远不会从内存中刷新,因此全局变量保留了应用程序上次运行时的值,例如:请考虑以下代码:

static int init = 0;

void android_main(struct android_app* state)
{
  init = 1;
  dostuff();
}

当我的应用程序第一次启动时,“init”为0并设置为1.从第二次运行开始,“init”将始终为1,因为* .so仍在内存中。但是我想要在调用android_main()时将全局变量重置为默认值!

那么有没有办法确保在调用android_main()之前总是重置全局变量,还是我必须手动执行此操作? (这对我的应用程序来说是一项巨大的工作,因为我有大量的全局变量分布在不同的* .c来源)

谢谢!

5 个答案:

答案 0 :(得分:5)

你在岩石和坚硬的地方之间。在共享库中初始化全局数据的摇滚本身实际上从未“初始化”。初始值实际上是在DATA部分的.so文件本身,只是在加载和Voila时被复制到内存中!初始化数据。

困难的地方是Java JNI设计没有UnloadLibrary(),并且指定要忽略对已加载库的LoadLibrary()的调用。

这更加复杂,因为您使用的是Android NativeActivity助手,它可以隐藏任何实际加载库的Java,以及活动代码本身,您可能(可能)可以结束活动当您的本机代码完成时。

我不确定转储NativeActivity,只是写一个瘦的JNI垫片会有很大帮助,因为你仍然无法卸载或重新加载本机代码,并明确结束Android中的活动可以有点棘手。实际上,我敢打赌你可以让活动干净可靠地结束 - 这不是我做的事情,所以我对它不是很熟悉。

另一种可能性是构建2个本机库。一个只是你的应用程序,根本就没有特定于Android的代码。另一个库是由NativeActivity加载的 - 使用android_main()和all - 它将使用dlopen()/ dlsym()/ dlclose()C API来加载,运行和清理“app”库。< / p>

认为它可以工作 - 但我从来没有尝试过。执行共享库内容的标头(dlfcn.h)位于NDK中。

答案 1 :(得分:3)

我发现的唯一解决方案是在本机c代码中调用exit() - 但是,这确实会产生关闭活动的副作用。有兴趣知道你是否找到了更好的解决方案吗?

答案 2 :(得分:0)

您必须手动执行此操作(即,除非您要显式结束应用程序)。正如你所说的那样,库仍然在内存中,直到它被破坏,据我所知,c中没有办法让数据像这样自发地重新初始化,至少在没有一些非常难看的黑客攻击的情况下,可能最终会成为更多的工作,然后手工完成。

答案 3 :(得分:0)

我处理onCreate / onDestroy事件并初始化/拆除这些函数中的所有全局变量。我的实现略有不同,因为我有一个Java活动,然后在onCreate / onDestroy函数中调用NDK代码,但是你可以直接覆盖NativeActivity :: onCreate(但我不知道因为我没有'试过这个)。

答案 4 :(得分:0)

嗨,我有一个类似的问题蹩脚:我已经将主函数编译为本机调用

但是当我用解码参数调用它时,在之后用编码参数调用它时函数失败了。我认为有些静态变量很脏。

我的解决方案是将共享库包含两次,一次用于编码,一次用于解码

也许这种解决方法可以帮助您