本文共 1837 字,大约阅读时间需要 6 分钟。
导读:
請教個共享庫的_init的簡單的問題我的一個共享庫,可以正確編譯,剛才加了_init和_fini函數後,再編譯,就報多重定義錯誤,是哪裡沒有設置好呢?請教……[root@skynet extension]# makegcc -fPIC -g -c libfw_sys-stat.c -o libfw_sys-stat.ogcc -shared -ldl -rdynamic -o libfw_print.so libfw_sys-stat.o -lclibfw_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 herelibfw_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 herecollect2: 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://srnob.baihongyu.com/