共享库构造函数未执行

时间:2011-04-13 08:09:45

标签: gcc constructor shared-libraries ld

我有以下问题。我写了一个共享库

#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.so 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-branch revision 160292](SUSE Linux)

提前感谢您的帮助!

编辑:2011-04-13,11:05

非常感谢luxifer,

文件间接帮助了!神奇的提示是,应该通过编译器让链接器参与......

  

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

工作!!!

2 个答案:

答案 0 :(得分:4)

Gcc的构造函数处理与ELF构造函数处理不同,而是位于它之上。要使用,您需要链接gcc启动文件中提供的粘合代码。

最简单的方法是使用gcc:

进行链接
gcc -shared -o testlib.so testlib.o

答案 1 :(得分:-3)

本文仅供参考,但为方便起见,我来到您的办公室:)

我不是该领域的专家,但谷歌快速搜索给了我this。只阅读文档的开头,如果我做对了,问题是:

静态链接你的程序在执行时是自包含的...它包含整个库,当你运行它时它已完全加载到内存中。

在执行时从程序调用库函数时动态链接链接器尝试通过查看某个库中是否有实现来解析所有未解析的函数引用。如果是这样,它会加载此实现,即仅加载函数代码。

因此,如果我做对了,动态链接器只加载部分库,即需要的函数,而不是整个库,那么这就解释了为什么在动态链接库时不调用构造函数。