23

動的共有ライブラリをプラグインとして使用するコードを書いています。

共有ライブラリを構築するための私のコマンド ラインは次のようになります。

cc -shared -fPIC -o module.so -g -Wall module.c

モジュール内では、メインの実行可能ファイル内にロードされた他の共有ライブラリにある関数を呼び出すことができます。

ただし、実行可能ファイル自体にある (エクスポートされた) 関数にアクセスできません (undefined symbolエラーが発生します)。

私の呼び出しはdlopen次のようになります。

void *handle = dlopen(plugin, RTLD_NOW);

実行可能ファイルのすべてのユーティリティ関数をさらに別の共有ライブラリに配置することなく、モジュールが実行可能ファイルにコールバックする方法を誰かアドバイスしてもらえますか?

4

3 に答える 3

35

正しい解決策は-rdynamic、メインの実行可能ファイルのリンク コマンドに追加することです。これにより、適切なオプションが追加されますld(を使用するGNU ldと、たまたま になります--export-dynamic)。

直接追加--export-dynamicすることは技術的に正しくありません。これはリンカー オプションであるため-Wl,--export-dynamic、 、またはとして追加する必要があります-Wl,-E。これは移植性も低くなり-rdynamicます (他のリンカーには同等のものがありますが、オプション自体は異なります)。

于 2009-01-27T07:31:38.367 に答える
8

私は自分で答えを見つけました。

--export-dynamicメインの実行可能ファイルのリンクオプションにフラグを追加する必要がありました。

動的にリンクされた実行可能ファイルを作成するときは、すべてのシンボルを動的シンボルテーブルに追加します。動的シンボルテーブルは、実行時に動的オブジェクトから表示されるシンボルのセットです。

このオプションを使用しない場合、動的シンボルテーブルには通常、リンクで言及されている動的オブジェクトによって参照されるシンボルのみが含まれます。

「dlopen」を使用して、他の動的オブジェクトではなく、プログラムによって定義されたシンボルを参照する必要がある動的オブジェクトをロードする場合、プログラム自体をリンクするときにこのオプションを使用する必要があります。

于 2009-01-26T17:40:38.717 に答える
4

同じ問題が発生したときは、次の解決策を使用しました。プラグインをロードする前に、プログラム自体をロードして、そのシンボルを動的テーブルに移動します。

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

解決策の方が良いと思います。その理由は、あなたが

a)プログラム(またはサードパーティモジュール)が共有ライブラリに対して(実行時ではなく)リンクされている。このシンボルは動的テーブルにある必要があります。

b)-rdynamicフラグを使用してそのモジュールを再コンパイルすることはできません。

于 2009-08-30T18:47:34.363 に答える