Библиотека сайта 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.
| Предыдущий раздел: | Оглавление | Следующий раздел: |
| Конструктор и деструктор | Данные в динамической библиотеке |
