Конструктор общей библиотеки не выполнен - PullRequest
8 голосов
/ 13 апреля 2011

У меня следующая проблема.Я пишу разделяемую библиотеку

#include <stdio.h>
#include <stdlib.h>

static void __attribute__ ((constructor)) test_init(void);
static void __attribute__ ((destructor))  test_clean(void);

/*  Initialization  */
static void     test_init(void){
        fprintf(stderr,"initialized\n");
        fflush(stderr);
}
/*  CleanUp */
static void test_clean(void){
        fprintf(stderr,"cleaned up\n");
        fflush(stderr);
}

double  test (double x){
    return  2.0*x;
}

и компилирую ее, используя

gcc -c -fPIC testlib.c -o testlib.o

ld -shared -o libtest.поэтому testlib.o

Затем я включаю его в тестовую программу

#include <stdio.h>
#include <stdlib.h>
extern double   test(double x);
void    main(void){

    printf("%.10e\n",test(10.0));
}

, которую я компилирую и начинаю использовать

gcc testprog.c -o testprog -L.-ltest

LD_LIBRARY_PATH =../testprog

Тогда вывод задается как

2.0000000000e + 01

, что означает, что конструктор / деструктор не выполняются.С другой стороны, если я скомпилирую

ar rvs testlib.a testlib.o

gcc testprog.c testlib.a -o testprog

, вывод программы будетзадано

testprog инициализировано 2.0000000000e + 01 очищено

Почему конструкторы не выполняются, если библиотека связана динамически?

Я использую следующие версии

GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6 gcc версия 4.5.0 20100604 [версия gcc-4_5-ветки 160292] (SUSE Linux)

Заранее благодарю за помощь!

Отредактировано: 2011-04-13, 11: 05

Спасибо большое luxifer,

документ помог косвенно!Волшебная подсказка заключалась в том, что нужно подключить компоновщик через компилятор ...

gcc -fPIC testlib.c -shared -Wl, -soname, libtest.so -o libtest.so

работает !!!

Ответы [ 2 ]

4 голосов
/ 13 апреля 2011
Обработка

Gcc constructor - это не то же самое, что обработка ELF-конструктора, скорее, она находится поверх него. Чтобы работать, вам нужно связать код клея, который предоставляется в файлах запуска gcc.

Самый простой способ сделать это - связать с помощью gcc:

gcc -shared -o testlib.so testlib.o
0 голосов
/ 13 апреля 2011

Этот текст предназначен для справки, но я приду к вам в офис для удобства:)

Я не эксперт в этой области, но быстрый поиск в Google дал мне это .Читая только начало документа, и, если я правильно его понял, проблема в следующем:

Статически связанная ваша программа во время выполнения автономна ... в ней целая библиотека, и она полностью загружена впамяти при запуске.

Связывается динамически, когда библиотечная функция вызывается из вашей программы во время выполнения, компоновщик пытается разрешить все неразрешенные ссылки на функции, проверяя, есть ли у него реализация в какой-либо библиотеке.Если это так, он загружает эту реализацию, то есть только код функций.

Так что, если я получу это право, и динамический компоновщик просто загрузит части библиотек, т.е. необходимые функции, а не всю библиотеку, тогда это объяснит, почему вашконструктор не вызывается, когда ваша библиотека динамически связана.

...