共享库构造函数未执行
我有以下问题。我编写一个共享库
#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 修订版 160292] (SUSE Linux)
预先感谢您的帮助!
编辑:2011-04-13, 11:05
非常感谢luxifer,
该文档间接提供了帮助!神奇的提示是,应该通过编译器涉及链接器......
gcc -fPIC testlib.c -共享 -Wl,-soname,libtest.so -o libtest.so
有效!!!
I have the following problem. I write a shared library
#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;
}
And compile it using
gcc -c -fPIC testlib.c -o testlib.o
ld -shared -o libtest.so testlib.o
Then I include it into a test program
#include <stdio.h>
#include <stdlib.h>
extern double test(double x);
void main(void){
printf("%.10e\n",test(10.0));
}
which I compile and start using
gcc testprog.c -o testprog -L. -ltest
LD_LIBRARY_PATH=. ./testprog
Then the output is given by
2.0000000000e+01
which means that the constructor/destructor are not executed. On the other hand, if I compile
ar rvs testlib.a testlib.o
gcc testprog.c testlib.a -o testprog
the output of the program is given by
testprog
initialized
2.0000000000e+01
cleaned up
Why are the constructors not executed if the library is linked dynamically?
I use the following versions
GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6
gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)
Thank you in advance for your help!
Edited: 2011-04-13, 11:05
Thank you very much luxifer,
the document helped indirectly! The magic hint was that one should involve the linker through the compiler...
gcc -fPIC testlib.c -shared
-Wl,-soname,libtest.so -o libtest.so
works!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Gcc 的构造函数处理与 ELF 构造函数处理不同,相反,它位于 ELF 构造函数之上。要工作,您需要链接 gcc 启动文件中提供的粘合代码。
最简单的方法是使用 gcc 进行链接:
Gcc's constructor handling is not the same thing as the ELF constructor handling, rather, it sits on top of it. To work, you need to link in the glue code that is provided in gcc's startup files.
The easiest way to do that is to link using gcc:
本文仅供参考,但为了方便起见,我来您的办公室:)
我不是该领域的专家,但快速的 Google 搜索给了我这个。只阅读文档的开头,如果我猜对了,问题是这样的:
静态链接你的程序在执行时是独立的......它包含整个库,并且当你运行它时它完全加载到内存中。
当在执行时从程序调用库函数时,链接器会尝试通过查看函数是否在某个库中具有实现来解析函数上所有未解析的引用,从而动态链接。如果是这样,它会加载此实现,即仅加载函数代码。
因此,如果我得到了正确的结果,并且动态链接器仅加载库的一部分(即所需的函数),而不是整个库,那么这将解释为什么当动态链接库时不调用构造函数。
This text is meant for reference, but I'm coming over to your office for convenience :)
I'm not an expert on that field but a quick Google search gave me this. Reading just the beginning of the document and if I get it right the problem is this:
Linked statically your program is self-contained at execution time... it has the whole library in it and it's completely loaded into memory when you run it.
Linked dynamically when the library function is called from your program at execution time the linker tries to resolve all unresolved references on functions by looking if it has an implementation in some library. If so it loads this implementation, i.e. just the functions code.
So if I get this right and the dynamic linker just loads portions of libraries, i.e. needed functions, and not the whole library then this would explain why your constructor isn't called when your library is linked dynamically.