10

ブースト共有ポインターを返し、それらをパラメーターとして使用する DLL を C++ で開発することは有効ですか?

では、このような関数をエクスポートしても問題ありませんか?

1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);

特に、参照カウントは DLL の境界を越えて機能しますか、それとも exe と dll が同じランタイムを使用することが要件になりますか?

その意図は、オブジェクトの所有権に関する問題を克服することです。そのため、dll と exe の両方がオブジェクトを参照しなくなると、オブジェクトは削除されます。

4

5 に答える 5

11

効果的な C++ (第 3 版) の Scott Meyers によると、shared_ptrs は dll の境界を越えて安全です。shared_ptr オブジェクトは、それを作成した dll からのデストラクタへのポインタを保持します。

アイテム 18 の彼の著書で、彼は次のように述べています。オブジェクトは、1 つのダイナミック リンク ライブラリ (DLL) で new を使用して作成されますが、別の DLL では削除されます. 多くのプラットフォームでは、このようなクロス DLL の新規/削除のペアは実行時エラーにつながります. tr1::shared_ptr は、デフォルトの削除ツールであるため、問題を回避します. tr1::shared_ptr が作成された同じ DLL から削除を使用します。"

ただし、Tim Lesher には注目すべき興味深い落とし穴があります。shared_ptr が最終的に範囲外になる前に、shared_ptr を作成した DLL がアンロードされていないことを確認する必要があります。ほとんどの場合、これは監視する必要はありませんが、疎結合の dll を作成している場合は、shared_ptr を使用しないことをお勧めします。

もう 1 つの潜在的な欠点は、ブースト ライブラリの互換性のあるバージョンで両側が作成されていることを確認することです。Boost の shared_ptr は長い間安定しています。少なくとも1.34以降はtr1 と互換性があります。

于 2011-11-10T19:03:35.643 に答える
4

私の意見では、それが標準に含まれておらず、ライブラリによって提供されるオブジェクト/メカニズムでもない場合は、ライブラリへのインターフェイスの一部であってはなりません。独自のオブジェクトを作成して参照カウントを実行し、その下でブーストを使用することもできますが、インターフェイスで明示的に公開しないでください。

于 2009-12-24T15:23:00.523 に答える
2

DLLは通常、リソースを所有していません。リソースは、DLLを使用するプロセスによって所有されています。プレーンポインタを返す方がおそらく良いでしょう。それを呼び出し側の共有ポインタに格納します。しかし、これ以上の情報がなければ、これについて100%確信することは困難です。

于 2009-12-24T15:21:56.190 に答える
2

dll インターフェイスから生のポインターを公開する場合は、注意が必要です。共有 dll CRT の使用を強制します。ある CRT に割り当てられたメモリは、別の CRT では割り当て解除できません。すべてのモジュール (dll と exe) で共有 dll CRT を使用する場合は問題ありません。それらはすべて同じヒープを共有します。

その問題は別として、私は受け入れられた答えに同意します。作成ファクトリは、おそらくクライアント コードの所有権とライフサイクル管理を定義するべきではありません。

于 2010-01-05T08:57:00.597 に答える
0

いいえそうではありません。

のレイアウトはboost::shared_ptr<T>、DLL 境界の両側で同じではない場合があります。(レイアウトは、Boost ソース コードの実際のバージョンだけでなく、コンパイラのバージョン、パッキング プラグマ、およびその他のコンパイラ オプションの影響を受けます。)

「標準レイアウト」(古い「POD = プレーンな古いデータ」の概念に関連する C++11 の新しい概念) 型のみが、個別に構築されたモジュール間で安全に受け渡すことができます。

于 2014-08-08T14:51:04.353 に答える