2011-04-13 77 views
8

我遇到以下问题。我写了一个共享库共享库构造函数未执行

#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-分支修订160292](SUSE Linux)的

预先感谢您的帮助!

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

非常感谢您luxifer,

文档间接地帮助了!神奇的暗示是一个应该包括通过编译链接...

的gcc -fPIC -shared testlib.c 轮候册,-soname,libtest.so -o libtest.so

作品!

+0

main()的返回类型为int。总是。 – Thomas 2012-04-13 21:26:46

回答

-2

本文是为参考,但我过来给您的办公提供方便:)

我不是对领域的专家,但快速谷歌搜索给了我this。只读文档的开始,如果我正确的解决了这个问题,问题是这样的:

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

动态链接时,库函数从你的程序在执行时被称为连接尝试通过查看它是否有一些库的实现,以解决上的功能都尚未解决的引用。如果是这样,它加载此实现,即仅仅是功能代码。

所以,如果我得到这个权利和动态连接器只是用来加载库的部分,即需要的功能,而不是整个库,然后这可以解释为什么当你的库是动态链接你的构造不叫。

4

Gcc的构造函数处理与ELF构造函数处理不是一回事,而是位于它的顶层。为了工作,你需要的是在GCC的启动文件中提供的胶水代码链接。

做到这一点的最简单方法是使用gcc链接:

gcc -shared -o testlib.so testlib.o