16

2 つの共有ライブラリ liba.so および libb.so。liba.so は libb.so を使用します。すべての c ファイルは -fPIC でコンパイルされます。リンクには -shared を使用します。liba.so で dlopen を呼び出すと、libb.so でシンボルを見つけることができません...「未定義のシンボル」エラーが発生します。エラーなしで libb.so を dlopen できます。ファイルが見つからないというエラーが発生しないため、liba が libb を見つけていることがわかります。libb.so を削除すると、ファイルが見つからないというエラーが発生します。-lutil を試しましたが、うまくいきませんでした。

何か案は????

そうそう。gcc 4.1.2

更新: liba をリンクするときに rpath を使用して、libb を見つけられるようにします。

ldd liba.so は以下を返します。

linux-gate.so.1 => (0xffffe000)  
libb.so => ./libb.so (0xf6ef9000)  <-------- LIBB 
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000)  
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000)  
libm.so.6 => /lib/libm.so.6 (0xf6ec9000)  
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000)  
librt.so.1 => /lib/librt.so.1 (0xf6ea8000)  
libc.so.6 => /lib/libc.so.6 (0xf6d62000)  
/lib/ld-linux.so.2 (0x007d0000)   

libb の末尾に .# がないことは意味がありますか???

4

2 に答える 2

26

次のコマンドlibb.soを使用して、どこにあると予想されるかを簡単に確認できます。ldd

 $ ldd liba.so
    linux-gate.so.1 =>  (0xb77b0000)
    libb.so.1 => not found
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
    /lib/ld-linux.so.2 (0xb77b1000)

の場合はnot found、パスをシェル変数またはシェル変数libb.soに追加する必要があります。/etc/ld.so.confLD_LIBRARY_PATH

もう 1 つの方法は、それ自体を設定rpathすることです。liba.soこれは基本的にそのパスをハードコーディングしているため、バイナリが開始されると、ダイナミック リンカーは共有ライブラリを検索する場所を認識します。

が設定されていない場合rpathは、最初に を検索し、次に(または /etc/ld.so.conf.d/)LD_LIBRARY_PATHに記載されているパスを検索します。/etc/ld.so.confに追加した後、ls.so.conf実行することを忘れないでください/sbin/ldconfig

ダイナミック リンカーは、依存する共有ライブラリをsoname(設定されているsoname場合) によって検索します。設定されていない場合 (たとえば -Wl,-soname,libb.so.1 を使用)、ライブラリの名前で検索されます。

例:libb.so.1.0実際のライブラリはsoname-libb.so.1です。通常、次のファイル構造があります。

libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0

libb.solibb.so.1シンボリックリンクです。

libb.soに応じて、通常、アプリケーションまたは他のライブラリを構築するときに、 にリンクしlibb.soます。

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb

アプリケーションが開始されると (または dlopen が実行される - あなたの場合) - ダイナミック リンカは名前を持つファイルを検索しますlibb.so.1-soname依存ライブラリのsonameが設定されている場合、 ではありませんlibb.so

libb.so.1そのため、実際のライブラリを指すsymlink が必要です。

と を使用するld.so.confldconfig、 の名前のシンボリック リンクが作成sonameされ、このシンボリック リンクが見つからない場合は、ライブラリ ファイルを指します。

より有用な情報については、 ld-linuxの man ページを参照してください。


ライブラリは見つかったが、一部のシンボルが見つからない場合は、オプションでビルドlibb.soしてみてください-Wl,--no-undefined

gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

シンボルの定義に失敗すると、エラーが発生するはずです。

于 2010-06-07T17:24:40.927 に答える
3

すべてのオブジェクトとライブラリをリンクして実行可能ファイルを生成するときは、ライブラリの順序 (すべての -lxxx 引数) が (少なくとも gcc では) 重要であることを忘れないでください。

短い例:

LIBS=-L。-ltest1 -ltest2

OBJS=code1.o code2.o

gcc $(LIBS) $(OBJS) -o mysoft

場合によっては失敗する可能性がありますが、

gcc $(OBJS) -o mysoft $(LIBS)

しません

于 2015-04-21T14:31:14.870 に答える