在我的共享库中,我必须在加载时进行某些初始化。如果我用 GCC 属性定义函数__attribute__ ((constructor))
它不起作用,即当加载链接我的共享库的程序时它不会被调用。
如果我将函数名称更改为_init()
, 有用。显然使用_init()
and _fini()
函数是不建议 http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP now.
知道为什么吗__attribute__ ((constructor))
行不通?这是Linux 2.6.9,gcc
版本3.4.6
Edit:
例如,假设库代码如下:
#include <stdio.h>
int smlib_count;
void __attribute__ ((constructor)) setup(void) {
smlib_count = 100;
printf("smlib_count starting at %d\n", smlib_count);
}
void smlib_count_incr() {
smlib_count++;
smlib_count++;
}
int smlib_count_get() {
return smlib_count;
}
为了构建 .so 我执行以下操作:
gcc -fPIC -c smlib.c
ld -shared -soname libsmlib.so.1 -o libsmlib.so.1.0 -lc smlib.o
ldconfig -v -n .
ln -sf libsmlib.so.1 libsmlib.so
由于 .so 不在标准位置之一,我更新了LD_LIBRARY_PATH
并从另一个程序链接 .so 。构造函数不会被调用。如果我把它改成_init()
, 有用。
好的,我已经看了一下,看起来发生的事情是你的中间gcc
步骤(使用-c
) 导致了这个问题。这是我对所看到内容的解释。
当你编译为.o
with setup()
, gcc
只是将其视为普通函数(因为您没有将其编译为.so
,所以它不在乎)。然后,ld
没有看到任何_init()
或类似的东西DT_INIT
在 ELF 的动态部分,并假设没有构造函数。
当你编译为.o
with _init()
, gcc
也将其视为正常功能。事实上,在我看来就像目标文件是相同的除了函数本身的名称!所以再一次,ld
看着.o
文件,但这次看到一个_init()
函数,它知道它正在寻找它,并确定它是一个构造函数,并相应地创建一个DT_INIT
进入新的.so
.
最后,如果您一步完成编译和链接,如下所示:
gcc -Wall -shared -fPIC -o libsmlib.so smlib.c
然后发生的事情是gcc
看到并理解__attribute__ ((constructor))
在创建共享对象的上下文中,并创建DT_INIT
相应地输入。
简短版本:使用gcc
一步完成编译和链接。您可以使用-Wl
(请参阅手册页)用于传递额外选项,例如-soname
如果需要的话,比如-Wl,-soname,libsmlib.so.1
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)