0

dlopenを使用してプログラム(P)によって動的にロードされるライブラリ(L)があります。Lはプラグインインターフェイスを実装しているため、親を呼び出していくつかの機能を取得します。

Pの内部には、スレッドプールオブジェクトAを動的に作成するシングルトンオブジェクトがあります。LからAにアクセスする必要があります。

ただし、シングルトンは静的変数を使用して機能するため、Lがロードされると、独自のインスタンスが作成されることになります。これは問題ない場合もありますが、Pで作成されたインスタンスが必要です。これを回避する方法はありますか?

4

2 に答える 2

1

宣言されたファイルスコープ名にstaticは内部リンクがあります。内部リンケージとは、ダイナミックライブラリのない「クラシック」リンクモデルであっても、他のトランスレーションユニットからは見えないことを意味します。スタティックは、同じ実行可能ファイル内の他の変換ユニットにも表示されないため、接続されているダイナミックライブラリから表示されると期待するのは合理的ではありません。

外部の動的シンボルを使用して必要なリンケージを実現する方法を考える必要があります。おそらく、シングルトンは単に内部名を持つことはできませんが、外部名を持つ必要があります。

Lは、オブジェクトが静的であるという理由だけでなく、そのシングルトンとスレッドプール機能を定義するスレッドプールモジュールをLにリンクしているという理由で、オブジェクトの独自のインスタンスを作成しています。これは、ライブラリがどのようにリンクされているかによっては、外部名を持つオブジェクトでも発生する可能性があります。

スレッドプールサービスが存在する単一のオブジェクトを選択し、それがそこにのみ存在することを確認する必要があります。あなたのプロジェクトには、この種のものに固執できるユーティリティライブラリがありませんか?

スレッドプールAPIを提供するのはプログラム実行可能ファイルPであるというモデルに固執することができます。これは本当に同じことです。プログラムPは別の動的オブジェクトであり、スレッドプールモジュールのライブラリとして効果的に機能し、それ自体と他の共有オブジェクトに提供します。

そのスレッドプールモジュールが存在する場所に関係なく、そのモジュールのコピーを他のオブジェクトに静的にリンクしていないことを確認してください。それは1か所にのみ存在します。

スレッドプールシングルトンの外部名がそのAPIの一部である場合(誰もがその文書化された名前を知っていて、それを直接使用し、そのグローバルプールをAPI関数に渡します)、その名前を外部にし、ヘッダーファイルで宣言する必要があります。

シングルトンをプライベートにする場合は、関数呼び出しで暗黙的にする(スレッドプールが1つしかない)、またはシングルトンへのアクセスをいくらか抽象化するなど、それを隠す方法を考える必要があります(ensure_thread_poolスレッドプールが存在しない場合はスレッドプールを作成する、またはスレッドセーフな方法で以前に作成したスレッドプールを返す)関数を提供します。

stdin考えてみてください。たとえば、なぜstdoutこの問題が発生しないのでしょうか。stdoutすべてのライブラリが独自のストリームをインスタンス化し、そのストリームで独自のfprintf関数を呼び出さないのはなぜですか?なぜ、明らかに、これらのものは1つの場所、つまりCライブラリに存在するからです。それらのコピーは他の場所に住んでいません。他の場所では、動的シンボルを介して参照するだけでそれらを使用します。

于 2013-02-21T00:43:40.373 に答える
1

LにAを含めることはできませんstatic。PがAのアドレスをLに渡すようにしますL.init(&A)

于 2013-02-20T23:59:46.797 に答える