Библиотека сайта rus-linux.net
Цилюрик О.И. Linux-инструменты для Windows-программистов | ||
Назад | Компиляция и сборка приложений | Вперед |
Подмена имён
Переопределение кода функций _init()
и _fini()
это
не есть самая хорошая идея, потому что мы затрагиваем структуру ELF
файла и можем породить нежелательные тонкие эффекты (как всегда с
функциями, начинающихся в имени с _). Но есть другие способы: просто
объявить свои произвольные функции как конструктор и деструктор
(каталог init
архива libraries.tgz
).
Перепишем реализацию библиотеки предыдущего примера, всё остальное, и
сборка — остаются неизменными:
hello_child.h : #include "../hello_child.h" #include <sys/time.h> static mark_time( void ) { struct timeval t; gettimeofday( &t, NULL ); printf( "%02d:%06d : ", t.tv_sec % 100, t.tv_usec ); } static mark_func( const char *f ) { mark_time(); printf( "%s\n", f ); } __attribute__ ((constructor)) void my_init_1( void ) { mark_func( __FUNCTION__ ); } __attribute__ ((constructor)) void my_init_2( void ) { mark_func( __FUNCTION__ ); } __attribute__ ((destructor)) void my_fini_1( void ) { mark_func( __FUNCTION__ ); } __attribute__ ((destructor)) void my_fini_2( void ) { mark_func( __FUNCTION__ ); } int put_my_msg( char *messg ) { mark_time(); printf( "%s\n", messg ); return -1; }
Вот как выглядит выполнение примера в таком виде:
$ export LD_LIBRARY_PATH=`pwd` $ ./hello_a 51:256261 : my_init_2 51:256345 : my_init_1 51:256365 : main 51:256384 : my_fini_1 51:256394 : my_fini_2
Мы определили сколь угодно конструкторов и деструкторов, в виде собственных функций, которые
могут с равным успехом вызываться и из программного кода приложения (но вот порядком
вызовов множественных конструкторов и деструкторов мы управлять не можем). Здесь работу за нас
выполняет ключевое слово __attribute__
— это одно из расширений компилятора
gcc
.
Предыдущий раздел: | Оглавление | Следующий раздел: |
Конструктор и деструктор | Данные в динамической библиотеке |