1

私の理解では、DLL の境界を越えて stl コンテナー ( などstd::string) を取得または返す関数を公開すると、2 つのバイナリ内のコンテナーの STL 実装の違いにより問題が発生する可能性があります。しかし、次のようなクラスをエクスポートしても安全ですか:

class Customer
{
public:
  wchar_t * getName() const;

private:
  wstring mName;
};

ある種のハックがなければ、mName は実行可能ファイルで使用できないため、mName でメソッドを実行することも、このオブジェクトを構築/破棄することもできません。

私の直感は「これはやらないでください、安全ではありません」ですが、正当な理由がわかりません。

4

6 に答える 6

5

問題ありません。より大きな問題に切り捨てられるため、そのクラスのコードを含むモジュール以外のモジュールに存在するコードで、そのクラスのオブジェクトを作成することはできません。別のモジュールのコードは、必要なオブジェクトのサイズを正確に知ることができず、 std::string クラスの実装が異なる可能性があります。宣言されているように、これは Customer オブジェクトのサイズにも影響します。たとえば、これらのモジュールの最適化ビルドとデバッグ ビルドを混在させると、同じコンパイラでもこれを保証できません。ただし、これは通常、回避するのが非常に簡単です。

そのため、Customer オブジェクトのクラス ファクトリ (同じモジュール内に存在するファクトリ) を作成する必要があります。これは、「mName」メンバーに触れるコードも同じモジュールに存在することを自動的に意味します。したがって、安全です。

次のステップは、 Customer をまったく公開せず、純粋な抽象基本クラス (別名インターフェース) を公開することです。これで、クライアント コードが Customer のインスタンスを作成するのを防ぎ、顧客の足を撃ち落とすことができます。また、std::string も自明に非表示にします。モジュールの相互運用シナリオでは、インターフェイス ベースのプログラミング手法が一般的です。また、COM が採用したアプローチ。

于 2013-05-29T20:35:48.130 に答える
0

本当に安全な DLL でオブジェクト指向インターフェイスを提供したい場合は、COM オブジェクト モデルの上に構築することをお勧めします。それがそのために設計されたものです。

異なるコンパイラでコンパイルされたコード間でクラスを共有しようとすると、失敗する可能性があります。ほとんどの場合、動作しているように見えるものを取得できる場合がありますが、動作を保証することはできません。

ある時点で、呼び出し規約、クラス構造、またはメモリ割り当てに関して、未定義の動作に依存する可能性があります。

于 2013-05-29T19:11:05.150 に答える