2009-06-03 7 views
2

リンクの問題があります。私は共有ライブラリlibfoo.soとリンクする必要があります。このライブラリは、read.cのファイルに自分自身を定義したい関数readに依存しています。nmのレポートのシンボルが定義されていますが、lddのレポートのシンボルが定義されていません

私はコンパイルと一緒にすべてをリンクしますが、実行時に、私はシンボルが

$nm baz | grep sread 
    00000000000022f8 t sread 

を定義したが、LDDは、シンボルが

$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so) 
を定義されていない報告された報告nmのエラー

/home/bar/src/libfoo.so: undefined symbol: sread. 

を取得

何ができますか? libfoo.soが共有ライブラリであるという事実を持つisseがありますか?

+0

あなたの共有オブジェクトと実行ファイルが完全にリンクされていなければ、被写体に光を当てるべきでしょう。 – lothar

答えて

13

まず、 'read'と呼ばれる関数を定義することは、すべてのUNIXenの標準libc関数であるため、悪い考え(TM)です。これを行うと、プログラムの動作は未定義です。

第2に、libbaz.soで定義したreadファンクションに't'が出力され、nm出力にマークされています。これは、この関数がローカルであることを意味します(libbaz.soの外側には表示されません)。グローバル関数は'T'nmとマークされています。

'static int read(...)'をread.cで定義したときに使用しましたか? コンパイルしてリンクしたときにコマンドラインにリンカースクリプトattribute((visibility(hidden)))または-fvisibility=hiddenを使用しましたか?libbaz.so

+0

関数の名前が実際には読み込まれていないので、私は物事を単純化しようとしていました。 Ahh ...あなたが正しいです-Wl、-version-scriptを使用しています。これには、エクスポートしたい2つ以外のすべてのシンボルをローカルに保持するファイルが含まれています。私は明らかにread関数もエクスポートする必要があります。 – codehippo

-1

共有ライブラリをビルドするときは、すべての未定義シンボルを同じライブラリ内または別の(共有)ライブラリ内で解決する必要があります。リンカーはではありません。は、ライブラリの未定義シンボルをアプリケーションのシンボルで解決します。

+0

私はbazが実際に共有ライブラリであることを明確にすべきです。だから、これは、私は読んだ関数だけを含む共有ライブラリを作成し、これとリンクする必要がありますか?共有ライブラリlibfoo.soの未定義シンボルを他の共有ライブラリ(libread.soなど)で解決するようにリンカに明示的に指示する方法はありますか? – codehippo

+2

あなたは間違いがあります:ランタイム・ローダーは、シンボルがダイナミック・テーブルでエクスポートされている場合(実行可能ファイルが-rdynamicでリンクされている場合など)、共有ライブラリの未定義シンボルをメイン実行可能ファイルのシンボルでうまく解決します。 。 –

+0

@ codehippoあなたはbazが共有ライブラリであり、その名前がその仮定にもつながっていないと言っていませんでした。 – lothar

1

上記のエラーは、C++コードがG ++でコンパイルされてリンクされている場合にも発生します。 G ++は名前のマングリングを実行するので、実際のシンボルは "_Zsds_ [function_name] _"のようなものになる可能性があり、アンマーグリングされていない名前を検索するときにリンカーがチョークします。

Wikipediaで概要を説明した操作に従って問題が解決されたことを除いて、今日は同じ動作になりました。基本的には、C++コンパイラでコンパイルされたCコードはシンボルテーブルに "mangled"という名前を持ち、Cスタイルのシンボル解決に失敗します。

関連する問題