2016-09-05 67 views
2

dlopen()在API-23中工作正常,但对于Android-N,当我试图用dlopen打开任何软件时,它返回一个soinfo结构类型指针。但是当我试图访问这个结构的任何变量时,应用程序就会崩溃。dlopen()与android-n不兼容

si = (soinfo*) dlopen("/data/app/com.xxx.xxx.sampleapp.android-1/lib/x86/libtest.so", RTLD_GLOBAL); 

if (si == NULL) 
    return; 

LOGI("value of dlopen [%d]", si->size); 

在Android-N中是否有任何dlopen()功能的变化?

回答

2

developer documentation(强调):

开始在安卓7.0,系统防止对非NDK库,这可能会导致应用程序崩溃动态链接的应用程序。这种行为变化旨在通过平台更新和不同设备创建一致的应用体验。
...
所有应用程序在调用既不公开也不临时访问的API时会生成运行时错误。 结果是System.loadLibrary和dlopen(3)都返回NULL,并可能导致您的应用程序崩溃。

+0

在提问中,提问者指出'dlopen'事实上并不返回NULL。还有其他事情必须在这里发生,你同意吗? –

+0

是的。它不会返回NULL。它返回一个无法访问的内存指针。这就是为什么我感到惊讶。 – vinit

+0

它实际上并不是一个_pointer_,它是一个_handle._含义:不要试图通过它访问内存。 –

7

dlopen()指针不回一些soinfo结构,它返回void*,标准的Linux手册页是非常具体的关于这一点:

函数dlopen()的加载动态共享对象(共享库)文件,该文件由以null结尾的字符串filename命名,并为加载的对象返回一个不透明的“句柄”。该句柄与dlopen API中的其他函数一起使用,例如dlsym(3),dladdr(3),dlinfo(3)和dlclose()。

,这样你可以以某种方式译作返回值的事实是非标准,现在谷歌仅仅是执行与this change

commit ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9 
author Dimitry Ivanov <[email protected]> 
... 
linker: hide the pointer to soinfo 

Handle no longer is a pointer to soinfo of 
a corresponding library. This is done to 
prevent access to linker internal fields. 

Bug: http://b/25593965 
Change-Id: I62bff0d0e5b2dc842e6bf0babb30fcc4c000be24 
(cherry picked from commit d88e1f350111b3dfd71c6492321f0503cb5540db) 

所以,除非你的应用程序的目标是SDK版本23或更低(请参阅soinfo::to_handle()),您现在正在获取只能转换回soinfo*的手柄,并带有内部仿生soinfo_from_handle()

+0

是的,我同意它返回无效*抱歉的错误.. – vinit

1

对于返回不透明句柄而不是指向soinfo的指针的Android版本,函数dl_iterate_phdr()可用。这可以让你找到所有.so's的Elf标题,而Elf标题包含大量与soinfo结构相同的信息。

相关问题