私は 2 つの dll エクスポート クラス A と B を持っています。A の宣言には、次のようなシグネチャで std::vector を使用する関数が含まれています。
class EXPORT A{
// ...
std::vector<B> myFunction(std::vector<B> const &input);
};
(EXPORT は、それに応じて _declspec(dllexport )/ _declspec(dllimport) を配置する通常のマクロです。)
DLL インターフェイスで STL クラスを使用することに関連する問題について読んで、要約すると次のようになります。
DLL インターフェイスで std::vector を使用するには、その DLL のすべてのクライアントを同じコンパイラの同じバージョンでコンパイルする必要があります。これは、STL コンテナーがバイナリ互換でないためです。さらに悪いことに、クライアントがその DLL を他の DLL と組み合わせて使用することによっては、システム アップデート (Microsoft KB パッケージなど) がインストールされたときに、「不安定な」DLL API によってこれらのクライアント アプリケーションが壊れる可能性があります (本当に?)。
std::vector<B>
上記にもかかわらず、必要に応じて、次のようにエクスポートすることにより、DLL API で std::vector を使用できます。template class EXPORT std::allocator<B>; template class EXPORT std::vector<B>;
ただし、これは通常、std::vector を A のメンバーとして使用する場合のコンテキストで言及されます(http://support.microsoft.com/kb/168958)。
次の Microsoft サポート記事では、DLL で作成された std::vector オブジェクトに、実行可能ファイル内からポインターまたは参照を介してアクセスする方法について説明しています (http://support.microsoft.com/default.aspx?scid=kb;EN-US; Q172396)。使用する上記のソリューション
template class EXPORT ...
も適用できるようです。ただし、最初の箇条書きでまとめた欠点は残っているようです。この問題を完全に取り除くには、std::vector をラップして
myFunction
、PIMPL などの署名を変更する必要があります。
私の質問は次のとおりです。
上記の要約は正しいですか、それともここで重要なことを見逃していますか?
クラス 'A' のコンパイルで警告 C4251 が生成されないのはなぜですか (クラス 'std::vector<_Ty>' には、... のクライアントが使用する dll-interface が必要です)? コンパイラの警告をオフにしておらず
myFunction
、エクスポートされたクラス A (VS2005 を使用) で std::vector を使用しても警告が表示されません。A で正しくエクスポートするには何をする必要があります
myFunction
か?std::vector<B>
Bのアロケータをエクスポートするだけで実行可能ですか?std::vector を値で返すことの意味は何ですか? 別のコンパイラ (-version) でコンパイルされたクライアント実行可能ファイルを想定しています。ベクトルがコピーされた場所で値渡しを返すときに問題が解決しませんか? はい。同様に、std::vector を定数参照として渡す場合:
std::vector<B>
(別のコンパイラ (-version) でコンパイルされた実行可能ファイルによって構築された可能性がある) にアクセスできますmyFunction
か? 私はまたそうだと思います..上記の最後の箇条書きが本当に唯一のクリーンな解決策ですか?
フィードバックをお寄せいただきありがとうございます。