web-dev-qa-db-ja.com

ATL :: CStringメンバーを含むクラスをエクスポートするDLLをビルドするときのC4251の警告

ATLベースの静的ライブラリをDLLに変換し、ATL CStringクラスを使用するエクスポートされたクラス(atlstr.hにあります)で次の警告を受け取ります:

警告C4251: 'Foo :: str_':クラス 'ATL :: CStringT'には、クラス 'Foo'のクライアントが使用するdllインターフェースが必要です

__declspec(dllexport)を介してエクスポートされるFooクラスを正しく宣言しています。これは無視しても安全な警告ですか、それとも何か問題がありますか? DLLプロジェクト設定は、ATLと動的にリンクするように設定されていますが、これによって違いが生じることはないようです。

例えば:

#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif

// This class is exported from the DLLTest.dll
class DLLTEST_API Foo
{
public:
 Foo();
 CString str_; // WARNING C4251 HERE
};

このDLLのすべてのクライアントもATLを使用します。

21
Rob

このスレッド は、Doug Harrison(VC++ MVP)による、私がより良い答えを考えているものを提供します。

[この警告は] dllexportedクラスYで非dllexportedクラスXを使用すると発生します。これの何が悪いのですか?さて、Yに、インラインではないXに属する関数x_fを呼び出すインライン関数y_fがあるとします。 Xを静的にリンクしないクライアント内でy_fがインライン化されている場合、x_fが見つからないため、リンクは失敗します。

18
Ofek Shilon
12
Yochai Timmer

これはスレッドです これについての良い議論。

要するに、コンパイラーは、実際には、エクスポートされたクラスがインターフェースを実装から分離しないことを警告しています。問題のメンバーがクライアントにアクセスできない場合は、メンバーをプライベートにして#pragmaそのメンバー/クラスの警告を取り除きます。メンバーがクライアントからアクセス可能で使用されている場合は、アクセサーとミューテーターを介してメンバーに間接アクセスを提供する必要があります。

8
John Dibling

Single/MultithreadedDLLではなく、Single/Multithreadedランタイムライブラリを使用してDLLをビルドするという愚かな間違いを犯したときに、通常この警告が表示されます。プロジェクト設定で確認することをお勧めします。

0
William Knight