で安全に使用STL(TR1)shared_ptrの間にモジュール(exesとdll)
-
19-08-2019 - |
質問
知っている新しいグループに何か一つのモジュールを削除-ingするかという問題がしばしば問題となりVC++.問題の異なるランタイム.混合モジュールstaticlyリランタイムおよび/または動的にリンクバージョンミスマッチの両方が機能することが可能でねじのものまで振り返ってみると、私のを修正
しかし、これを安全に使用VC++2008のstd::tr1::shared_ptr全モジュール?
に限りがありショールーム:イメージは、ランタイムでも何かshared_ptrは、静的リンクはかなりの危険を今...).と思ったこのままboostのバージョンのshared_ptrした安全な使用、このようなものを使用していRedmondのバージョン---
私の手続きを避けるための特別な通話を無料のオブジェクトの配分モジュールです。(いのも長いのもどっちも似合は、"削除"をクラス自体です).この全なインター hackyが、私が使っているこのユニットテスト。だっ単体テストまで、既存のC++コードを理解することができ方 創造 る必要があります。私のメモリの割り当てによるEXEが、最終的には解放され、DLL場合のリファレンスカウンターでの作品の方法と思うな).
解決
メモリの解放は、すべてが同じメモリ管理コンテキストからのものである限り安全です。最も一般的な問題(異なるC ++ランタイム)を特定しました。別のヒープを使用することは、もう1つのあまり一般的ではない問題です。
言及しなかったが、共有ポインタによって悪化する可能性のある別の問題は、オブジェクトのコードがDLLに存在し、DLLによって作成されるが、DLLの外部の別のオブジェクトがそれへの参照で終わる場合です。 (共有ポインタ経由)。 DLLがアンロードされた後にそのオブジェクトが破棄された場合(たとえば、モジュールレベルの静的オブジェクトである場合、またはFreeLibrary()
によってDLLが明示的にアンロードされた場合、共有オブジェクトのデストラクタがクラッシュします。
これは、DLLベースの疎結合プラグインを作成しようとすると、噛みつきます。また、COMがDLLをアンロードできるタイミングをDLLに決定させるのは、COMサーバーにそれらをデマンドアンロードさせるのではなく、理由です。
他のヒント
ん初めかを見るのは非常に驚き shared_ptr
は:)
安全横断DLLの境界はどの shared_ptr
した設計として使用することができるものです。
逆にそういうものに合格する必要があり、カスタムdeleterを構築する際 shared_ptr
, としてのデフォルトでのようなもの
template <typename T>
struct default_deleter {
void operator()( T * t ) { delete t; }
};
や
shared_ptr<Foo> foo( new Bar );
に相当
shared_ptr<Foo> foo( new Bar, default_deleter<Bar>() );
ります。はありませんし shared_ptr
なdeleter).
では消去を行いdeleter、 delete
ことになるといいま 常に 一からDLLをその インスタンスを生成 の shared_ptr
, いつからDLLを shared_ptr
の範囲(ie.の shared_ptr
メソッドを呼び出して、deleter通のテーマによってポインタ機能を入れているの shared_ptr
).
と比較することによ auto_ptr
, を埋め込むには delete
オペレーターを直接におけるインライン)のデストラクタは、 delete
のDLLをその 破壊 の auto_ptr
使用、同じ問題を削除した裸のポインタです。
同一の技術、多様な授業を常時開催 shared_ptr
sな仮想デストラクタでは、deleterは常に、権デストラクタでも、前 shared_ptr
の範囲はインスタンスを生成のための基底クラスです。
懸念がある場合は、deleter引数をとるshared_ptrコンストラクターの形式を使用します。削除者は、適切なコンテキストで削除が行われるように、オブジェクトを割り当てたモジュールにコールバックできます。
Boostのドキュメントは、TR1と100%互換性があると主張しているので、これについて誤解を招くものがないことを願っています:
http://www.boost.org /doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm#constructors
モジュール間でstd
のクラスを使用するのと同じくらい安全だと思います。
つまり:モジュールがまったく同じランタイムライブラリを使用し、まったく同じコンパイラスイッチとオプションを使用している場合は安全です。
各モジュールはその中のすべてのグローバルの独自のインスタンスを取得するため、静的ランタイムライブラリを使用しないでください。
一般的なテーマで私が見た最良のアドバイスは、割り当てられたのと同じコンテキストでメモリの割り当てを解除する必要があるということです。ただし、アプリケーションコードが解放するはずのポインタをライブラリが返すことを妨げるものではないため、一般的な状況であるため、この方法でshared_ptrを渡すことはおそらく安全だと思います。
システムのセマンティクスにより、ポインターが実際に(所有権の意味で)exeからdllに転送されることを意味する場合、auto_ptrがより良い解決策になる可能性があります。ただし、ポインターが本当に共有されている場合、shared_ptrがおそらく最適なソリューションです。