請教個共享庫的_init的簡單的問題

来源:互联网 发布:h5牛牛源码搭建教程 编辑:程序博客网 时间:2024/06/03 18:38
导读:




請教個共享庫的_init的簡單的問題

我的一個共享庫,可以正確編譯,剛才加了_init和_fini函數後,再編譯,就報多重定義錯誤,是哪裡沒有設置好呢?請教……

[root@skynet extension]# make
gcc -fPIC -g -c libfw_sys-stat.c -o libfw_sys-stat.o
gcc   -shared  -ldl -rdynamic -o libfw_print.so libfw_sys-stat.o -lc
libfw_sys-stat.o(.text+0x4fa): In function `_init':
/root/develop/cgi/extension/libfw_sys-stat.c:143: multiple definition of `_init'
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crti.o(.init+0x0):/usr/src/build/231499-i386/BUILD/glibc-2.3.2-20030313/build-i386-linux/csu/crti.S:12: first defined here
libfw_sys-stat.o(.text+0x524): In function `_fini':
/root/develop/cgi/extension/libfw_sys-stat.c:148: multiple definition of `_fini'
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crti.o(.fini+0x0): first defined here
collect2: ld returned 1 exit status





_init函數是做什麼的, 有什麼特殊用途嗎? 可能gcc鏈接的一些基本庫中已經定義了這個符號, 所以會發生衝突。
GCC的話,可以用__attribute__來指定一個函數在main()之前運行:
void foo1(void) __attribute__( (constructor) );





從編譯信息看是和缺省的庫中已有的定義名字重複了





-->

Linux中,共享庫的_init有點類似於模塊編程的module_init,在庫加載時的初始化動作,我看所有的教程都是這麼做,我照著做出來,結果卻報「重複定義」,鬱悶,我想是不是編譯器有什麼開關參數之類的東東啊?





ELF規範半途而廢, 也不記得什麼了。 好像._init是個section, 試試把函數定義在這個section中如何?
void foo(void) __attribute__((section("._init")));
看行不行? 我不確定,畢竟沒做過





-->

共享庫中的_init改成另外一個名字,例如myinit,編譯增加選項:
gcc ... -Wl,-init=myinit





-->

我試了上面哪個attribute方法,發現myinit沒被調用;-Wl給鏈接器傳遞參數的方法, myinit還是沒有被調用……





-->

你在什麼系統上試的?我在redhat9下試是可以的:

-bash-2.05b# cat myfunc.c
#include

void myinit(void)
{
    printf("in myinit/n");
}

-bash-2.05b# cat demo.c

int main(int argc, char *argv[])
{
    return 0;
}

-bash-2.05b# gcc -o libmyfunc.so -fPIC -shared -Wl,-init=myinit myfunc.c
-bash-2.05b# gcc -o demo demo.c -L. -lmyfunc
-bash-2.05b# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
-bash-2.05b# demo
in myinit





-->

關於共享庫的_init和_fini的加載,gcc編譯需要一個開關參數,需要加一個「-nostartfiles」選項。這個選項使得C編譯器不鏈接系統的啟動函數庫裡面的啟動函數。





-->


果然是簡單直接的解法。


本文转自
http://www.lslnet.com/linux/f/docs1/i47/big5323681.htm
原创粉丝点击