3

単一の EXE と複数の DLL に分割された C/C++ で記述されたアプリケーションがあります。これらの DLL はそれぞれ、同じ静的ライブラリ ( utilities.lib) を使用します。

ユーティリティ スタティック ライブラリ内のすべてのグローバル変数は、実際には、実行時にアプリケーション内で複数のインスタンスを持ちます。utilities.libリンク先のモジュール (つまり、DLL または EXE) ごとにグローバル変数のコピーが 1 つ存在します。

(これはすべて既知であり、良いことですが、DLL のコンテキストで静的ライブラリがどのように動作するかについて、背景を説明する価値があります。)

さて、私の質問.. utilities.libDLL になるように変更したいと思います。これは非常に大きく複雑になってきているため、形式ではなく DLL 形式で配布したいと考えています.lib。問題は、この 1 つのアプリケーションについて、各アプリケーション DLL がユーティリティ ライブラリ内のグローバル変数の独自のコピーを持つという現在の動作を維持したいということです。 これをどのように行うつもりですか? 実際には、すべてのグローバル変数にこれが必要なわけではなく、一部だけです。しかし、私たちがすべて手に入れたとしても問題ではありません。


私たちの考え:

  1. ライブラリ内に関心のあるグローバル変数はそれほど多くありませんが、どの DLL がそれを呼び出しているかを特定しようとするファンキーなトリックを実行するアクセサでそれぞれをラップすることができます。おそらく、コール スタックHMODULEを調べて、そうでない関数が見つかるまで for each 関数を探し出すことができutilities.dllます。次に、呼び出し元の DLL に応じて異なるバージョンを返すことができます。
  2. の関数を呼び出す前に、呼び出し元が特定のグローバル変数 (おそらくスレッド ローカル変数) を設定することを義務付けることができますutilities.dll。ユーティリティ DLL は、このグローバル変数値を使用して呼び出しコンテキストを決定できます。
  3. utilities.dll実行時に複数回ロードする方法を見つけることができました。おそらく、各アプリケーション DLL がユーティリティ DLL の独自のコピーを持つことができるように、ビルド時に名前を変更した複数のコピーを作成する必要があります。これは、そもそも DLL を使用する利点の一部を無効にしますが、この「静的ライブラリ」スタイルの動作が不要でありutilities.libutilities.dll.
4

2 に答える 2

2

これを行う場合、すべてのステートフル グローバル変数を除外します。必要なすべての状態を含む COM オブジェクトまたは単純な C++ クラスをエクスポートすると、各 DLL エクスポートがクラスのメソッドになります。

特定の質問への回答:

  1. そのようなスタック トレースを確実に実行することはできません。テール コールの最適化FPOなどの最適化により、すべての場合に誰があなたを呼び出したかを特定することはできません。プログラムがデバッグで動作し、ほとんどがリリースで動作しますが、ときどきクラッシュすることがわかります。
  2. これを管理するのは難しいと思います。また、ライブラリがプロセス内の他のモジュールと再入可能にできないという要求も課せられます。たとえば、他のモジュールへのコールバックやイベントをサポートしている場合などです。
  3. これは可能ですが、DLL を使用するポイントを完全に否定しています。名前を変更するのではなく、別のディレクトリにコピーしてフル パス経由でロードすることができます。
于 2009-07-02T21:49:24.647 に答える