dlopenでライブラリをロードするときに「未定義のシンボル」エラーを受信します
-
20-08-2019 - |
質問
ダイナミック共有ライブラリをプラグインとして使用するコードを書いています。
共有ライブラリを構築するための私のコマンドラインは次のように見えます:
cc -shared -fPIC -o module.so -g -Wall module.c
モジュール内で、メイン実行可能ファイル内にロードされた他の共有ライブラリにある関数を呼び出すことができます。
ただし、実行可能ファイル自体にある(エクスポート)機能にアクセスできません(わかります undefined symbol
エラー)。
私の電話 dlopen
このように見えます:
void *handle = dlopen(plugin, RTLD_NOW);
実行可能ファイルのすべてのユーティリティ機能をさらに別の共有ライブラリに入れることなく、私のモジュールが実行可能ファイルにどのようにコールバックできるかをアドバイスできますか?
解決 2
私は自分で答えを見つけました。
私は追加しなければなりませんでした --export-dynamic
メイン実行可能ファイルのリンクオプションへのフラグ。
動的にリンクされた実行可能ファイルを作成するときは、すべてのシンボルを動的シンボルテーブルに追加します。動的シンボルテーブルは、実行時に動的オブジェクトから表示されるシンボルのセットです。
このオプションを使用しない場合、動的シンボルテーブルには通常、リンクに記載されている動的オブジェクトによって参照されるシンボルのみが含まれます。
「dlopen」を使用して、他の動的オブジェクトではなく、プログラムによって定義されたシンボルを参照する必要がある動的オブジェクトをロードする場合、プログラム自体をリンクするときにこのオプションを使用する必要があります。
他のヒント
正しい解決策は追加することです -rdynamic
メイン実行可能ファイルのリンクコマンドへ。これにより、適切なオプションが追加されます ld
(使用するとき GNU ld
, 、たまたまそうです --export-dynamic
).
追加 --export-dynamic
技術的には正しくありません:それはリンカーのオプションであるため、として追加する必要があります -Wl,--export-dynamic
, 、 また -Wl,-E
. 。これも携帯性が低くなります -rdynamic
(他のリンカーには同等のものがありますが、オプション自体は異なります)。
同じ問題に遭遇したとき、次のソリューションを使用しました。プラグインをロードする前に、プログラム自体をロードするだけで、そのシンボルを動的テーブルに持ち込みます。
dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);
解決策は良いと思います。その理由は、あなたが同じ問題も解決するからです
a)プログラム(またはTrird-Partyモジュール)は、共有ライブラリにリンクされています(ランタイムではありません)。シンボルは動的テーブルにある必要があります。
b)rdynamicフラグを持つモジュールを再コンパイルすることはできません。