2011-08-31 10 views
10

私は、dlopen()を使用してプログラムによって開かれる共有オブジェクトライブラリを構築しようとしています。このライブラリは、静的な別のライブラリによって提供される機能を使用します。静的ライブラリのシンボルを共有ライブラリビルドに含める方法を教えてください。

動的なリンクをリンクするときにリンク線に適切なフラグを設定しています(例:libfoo.aに-lfooがある)、リンカーは不平を言っていません。ただし、メインプログラムがダイナミックライブラリのdlopen()を呼び出すと、静的ライブラリのシンボルを参照する "未定義シンボル"メッセージが表示されて呼び出しが失敗します。

nmを実行すると、問題のシンボルがダイナミックライブラリで定義されておらず、メインプログラムにはそのシンボルが含まれていないことを示しています。シンボル自体は初期化されていないデータセクションにあります(nm出力のシンボルタイプ "B")。

答えて

14

リンカーオプション--whole-archiveがこれを行う必要があります。たとえば、

gcc -o libmyshared.so foo.o -lanothersharedlib -Wl,--whole-archive -lmystaticlib 

あなたが経験しているのは、デフォルトでは、リンカはバイナリあなたがニーズを生み出す静的アーカイブ内のシンボルを検索することであり、それが1つを必要とする場合、その全体の.oが含まれます共有ライブラリにシンボルが必要ない場合は、共有ライブラリには含まれません。

共有ライブラリになるコードは、共有ライブラリに静的ライブラリを含めるので、-fpicなどの特別なオプションでコンパイルする必要があることに注意してください。静的ライブラリは同じオプションでコンパイルする必要があります。

8

最近、私は同じ解決策を探していました。 私は

--undefined=symbol 

または

-u symbol 

を使用して問題を解決しました。

+0

'--whole-archive'という答えは、アーカイブ内のすべてのシンボルを共有ライブラリのエクスポートシンボルに変換します。あなたがただ一つのシンボルを必要とするならば、この答えはあなたの.soにはるかに少なく膨らんでいます。 – MuertoExcobito

4

もう1つのハックは、ライブラリの初期化中にどこかの関数のアドレスを取得することです。これにより、シンボルが実際に使用されていることが確認されます。

+3

downvoterに:私は言った、 "ハック" – user877329

関連する問題