5

2 つの異なる dllに 2つの静的オブジェクトがあります。

オブジェクトResources (シングルトン) とオブジェクトUser。デストラクタ内の Object User は、オブジェクト Resources にアクセスする必要があります。

オブジェクト User の前にオブジェクト Resources が破棄されないようにするにはどうすればよいですか?

4

4 に答える 4

4

その 2 つのグローバル変数を同じ DLL に入れることができる場合、それは同じ話ではありません。Jem 自身の返信で述べたように、DLL の切り離し順序はシステムによって保証されていません。したがって、2 つの別個の DLL がある場合、大きな問題が発生する可能性があります。私は Windows システムの第一人者ではありませんが、Google で調べてみると、同じ問題を抱えていて、それに対処するための良い解決策がないと言っている msdn ブロガーを見つけました。

それらを1つの同じDLLに入れることができます.私によると、解決策は簡単です.
ただし、新しい問題に対処する必要があります。グローバル変数の破棄順序は、C++ 言語によって保証されていません。しかし、これは対処できます:

何らかの参照カウントを使用する必要があります。boost::shared_ptr がうまくいくかもしれません。

それをグローバルに宣言し、そのように定義します。

boost::shared_ptr my_resource_ptr ( new Resource() ); // new operator is important here!

次に、独自の shared_ptrを格納するように User 実装を変更する必要があります。

class User
{
    ...
    boost::share_ptr a_resource_ptr;
    ...
};

User インスタンスのすべてが破棄されない限り、それらは Resource インスタンスを「保持」し、グローバルな shared_ptr が破棄された可能性がある場合でも、リソース インスタンスが途中で削除されるのを防ぎます。
破棄される最後の User インスタンスは、(間接的に) Resource インスタンスを削除します。

使用する参照カウントが何であれ、ComPtr、独自の参照カウントは、うまくいくはずです。

于 2009-05-16T23:45:57.830 に答える
3

グローバル オブジェクトは、対応する DLL がアンロードされると破棄されます。したがって、'User' dll はおそらく 'Resource' dll に依存しているため、問題が発生します。'resource' は常に 'user' の前に破棄されます。

この質問に対する適切な回答があれば、それにも興味があります。これまでは、アプリケーションが終了する前に呼び出さなければならないクリーンアップ関数を使用しており、デストラクタには無害なコードのみを保持しています。

于 2009-05-16T10:46:56.067 に答える
1

異なるモジュールにあるグローバルの破棄の順序を変更できるとは思いません。参照カウントを追加する可能性はありますか?

于 2009-05-16T15:29:45.200 に答える
1

本当に 2 つの個別の Dll を取得したい場合は、いくつかのヒントがあるかもしれません: FreeLibrary()Windows API からの使用を検討してください。msdn で述べたようFreeLibrary()に、カウンターが 0 に達するとアンロードされる Dll の参照カウンターをデクリメントします。

欠点: usingは( msdn linkFreeLibrary() )でロードしていることを意味し、このライブラリから function を呼び出していることは、関数を使用していることを意味するため、非常に見苦しいコードになる可能性があります。また、コードの変更も意味する場合があります-各関数のアドレスを保存するためにDLLの関数にグローバル変数をポイティングするなど...LoadLibrary()GetProcAddress()

実装したい場合:

  1. main()プロセスの関数 からライブラリをロードして解放する必要があります。
  2. また、User クラスを実装する Dll からライブラリをロードして解放します。DllMain()理由がある場合は、この Dllの関数に実装しますDLL_PROCESS_DETACH( mdsn の DllMain リンクを参照してください。

したがって、「ユーザー」ライブラリが終了した場合にのみ、「リソース」ライブラリをアンロードします。

試してみて、実装したことがないのでうまくいくかどうか教えてください..

Ps: 私はあなたの質問に 2 番目の回答を投稿して、2 つの回答を明確に区別できるようにしました。それらを混同して混乱させたくない...

于 2009-05-17T02:18:12.443 に答える