gcc下__attribute__ ((constructor))和__attribute__ ((destructor))的使用
__attribute__ ((constructor))指定的函数在共享库loading的时候调用,__attribute__ ((destructor))指定的函数在共享库unloading的时候调用。
1. 编写源码文件ktest.c如下.
- #include <stdio.h>
- __attribute__ ((constructor)) static void ktest_init(void);
- __attribute__ ((destructor)) static void ktest_deinit(void);
- void ktest_init(void)
- {
- printf("call ktest init./n");
- }
- void ktest_deinit(void)
- {
- printf("call ktest deinit./n");
- }
- void test1()
- {
- printf("call test1./n");
- }
- void test2()
- {
- printf("call test2./n");
- }
- void test3()
- {
- printf("call test3./n");
- }
2. 编译为共享库libktest.so
- gcc -fPIC -c ktest.c ### produce ktest.o.
- gcc -shared -o libktest.so ktest.o ### produce libktes.so
3. 编写库调用文件calllib.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <dlfcn.h> /* dlopen, dlsym, dlclose */
- int main(int argc, char **argv)
- {
- test1();
- test2();
- test3();
- /* below only for testing dynamic linking loader */
- void *handle;
- void (*test)();
- char *error;
- handle = dlopen ("/path_to_lib/libktest.so", RTLD_LAZY);
- if (!handle) {
- fputs (dlerror(), stderr);
- exit(1);
- }
- test = dlsym(handle, "test2");
- if ((error = dlerror()) != NULL) {
- fputs(error, stderr);
- exit(1);
- }
- (*test)();
- dlclose(handle);
- return 0;
- }
4. 编译calllib运行, 将可以看到ktest_init() 和ktest_deinit()已被调用.
- gcc calllib.c -o calllib -ldl -L./ -lktest ### produce calllib
- export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH && ./calllib
call ktest init.
call test1.
call test2.
call test3.
call test2.
call ktest deinit.