constructor属性函数在动态库加载中的执行顺序
发布时间:2023-01-12 11:08:50 所属栏目:Linux 来源:
导读: void __init() __attribute__((constructor(100)));
目标可执行文件在执行的时候有时会加载不同的动态库,比如动态库libA.so 和libB.so。 动态库中各自包含constructor属性修饰的函数,当动态库被加载时
目标可执行文件在执行的时候有时会加载不同的动态库,比如动态库libA.so 和libB.so。 动态库中各自包含constructor属性修饰的函数,当动态库被加载时
|
void __init() __attribute__((constructor(100))); 目标可执行文件在执行的时候有时会加载不同的动态库,比如动态库libA.so 和libB.so。 动态库中各自包含constructor属性修饰的函数,当动态库被加载时,该函数会自动执行。而且执行顺序与动态库的加载顺序恰好相反。下面是我找到的英文解释: The invocation of _init() functions follows in the reverse order of library loading (for example, the first library loaded is the last to call _init()). This reversed ordering is necessary because libraries appearing earlier on the link line might depend on functions used in libraries appearing later 简单的小例子: A.c文本中: void __attribute__((constructor)) __initA() { printf("initA\n"); } B.c文本中: void __attribute__((constructor)) __initB() { printf("initB\n"); } 执行分析: bryli@diag-bld-07-g1:/ws-bryli/code$ gcc -Wall -fPIC -c A.c B.c bryli@diag-bld-07-g1:/ws-bryli/code$ gcc -shared -o libA.so A.o bryli@diag-bld-07-g1:/ws-bryli/code$ gcc -shared -o libB.so B.o bryli@diag-bld-07-g1:/ws-bryli/code$ gcc -L/ws-bryli/code -Wall main.c -o main -lA -lB bryli@diag-bld-07-g1:/ws-bryli/code$ ldd main linux-vdso.so.1 (0x00007ffd27494000) libA.so => /ws-bryli/code/libA.so (0x00007fe33b24e000) libB.so => /ws-bryli/code/libB.so (0x00007fe33b04c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe33ac5b000) /lib64/ld-linux-x86-64.so.2 (0x00007fe33b652000) bryli@diag-bld-07-g1:/ws-bryli/code$ ./main initB initA 可执行文件先加载A后加载B,但是libB.so中的init先执行,libA.so中的init后执行,刚好验证了前面的论述。 在实际工作中,常常会有很多层动态库,有的动态库是底层函数的封装,有的动态库负责上层函数的封装。上层的动态库往往会依赖于下层的动态库,所以我们编译的时候会先加载上层的的动态库linux动态库,后加载下层的动态库,保证编译正确。在这种情形下,constructor属性函数的动态库,会先执行下层动态库中的constructor中的函数,后执行上层的。 (编辑:我爱资讯网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐


