本篇文章主要介绍了"Android C语言_init函数和constructor属性及.init/.init_array节探索",主要涉及到Android C语言_init函数和constructor属性及.init/.init_array节探索方面的内容,对于Android C语言_init函数和constructor属性及.init/.init_array节探索感兴趣的同学可以参考一下。
了解C语言的程序猿都知道有两种方法可以让一部分代码在so或可执行文件被加载的时候先于其它任何函数执行,一种是定义一个void _init(void)函数,另一种是在函数后面声明constructor属性。那么这两种方式在执行的时候有什么区别吗?先后顺序呢?了解ELF文件格式的人又会问它们在文件中的位置又有什么差别呢?这篇文章就来解答这些问题。
首先你需要了解一下ELF文件格式了,这里就不啰嗦了,不了解的人可以搜一下看看。
下面是一个例子,在你的Android工程中的C/C++代码中加入下面几行:
........
#ifdef __cplusplus
extern "C" {
#endif
void _init(void){mlog_info("_init enter");}
#ifdef __cplusplus
}
#endif
void __attribute__((constructor)) myConstructor(void){mlog_info("myConstructor enter\n");}
........
我这边编译出来是libcheckcert.so文件,放到手机上去运行的结果是:
........
12-13 11:04:46.603: I/BRIAN(12203): _init enter
12-13 11:04:46.603: I/BRIAN(12203): myConstructor enter
........
_init函数是最先运行的,为什么会这样呢?了解ELF文件的人都知道有.init和.init_array这两个节,它们是ELF文件在加载的时候用来做初始化的,那么它们和_init函数及constructor属性有什么关系呢?下面我们需要借助readelf和I