android - 在 Android-ndk 中,如何在调用 dlclose( ) 时调用 _fini( )?
问题描述
我们在我们的 Android-NDK 项目中使用 C 库。我们正在使用 dlopen() 和 dlclose() 来处理我们在 Android NDK 中的库。当我们调用 dlopen() 时,库的 _init() 会按预期被调用。但相反,当我们使用 dlclose() 调用关闭库时,_fini() 函数不会被调用。我们不想在调用 dlclose( ) API 之后显式调用 _fini( ) 函数。我正在 API 24 上测试这些。
根据 linux,当我们分别调用 dlopen( ) 和 dlclose( ) 时,应该调用 _init( ) 和 _fini( ) 这两个函数。
void func( ){
...
int ret = -1;
handle = dlopen( "mylib.so", RTLD_NOW | RTLD_GLOBAL );
ret = dlclose( handle ); // dlclose() is returning 0.
...
}
void _init( ){
log("dlopen is loading the library");
}
void _fini( ){
log("dlclose is unloading the library");
}
我还尝试如下更改 _fini( ) 的语法,但没有运气。
void _fini() __attribute__((destructor));
即使使用上一行中的“析构函数”属性,_fini() 也不会被 dlclose() 调用。
由于 _init() 函数在 dlopen() 上被调用,我确信 _fini() 也应该在 dlclose() 上被调用,所以我应该遗漏一些东西。我们正在使用 Android Studio 来构建 apk。谁能帮我解决这个问题。提前致谢。
解决方案
我能给出的最好建议dlclose
是永远不要使用dlclose
.
dlclose
除了通知运行时它可以卸载库之外,没有指定做任何事情;运行时不必对此做任何事情。对于实现卸载的系统(包括Android)并不总是能够这样做,因为atexit
在整个程序退出之前无法运行处理程序(或线程退出处理程序等),因此任何时候库注册这样的处理程序都不能卸载。这里似乎就是这种情况。
确切的用例可能会导致答案有所不同,但对于我们已经看到的这种行为无法删除的情况(插件接口,预计插件会卸载,然后重新加载所有状态重置),修复是向库中添加显式Initialize()
和ShutDown()
函数。这些需要由库用户调用,而不是依赖dlopen
/ dlclose
。
推荐阅读
- shell - 如何使用 Terraform 将变量更改为值的文件从本地复制到远程?
- 3d - 如何重新排序尺寸?
- python - BitBucket 上 PyMonad 的概述页面
- java - 如何在java中使用一些改变的模式修改文本内容
- php - php while循环中数组的最大值
- docker - 在 Docker 映像的 kubernetes 挂载卷中找不到现有的二进制可执行文件
- dynamics-crm - 在 Dynamics 365 API 中,当所有者可以是系统用户或团队时,如何引用正确的所有权实体以获取详细信息?
- kubernetes - 计算 Kubernetes 中的优势资源
- reactjs - 为什么这个反应应用程序只在开发工具打开的情况下更新新内容?
- ansible - 在 ansible “when” 语句中使用波浪号从变量构建文件名