2010-01-25 16 views
13

Konwertuję bibliotekę statyczną opartą na ATL na bibliotekę DLL i otrzymuję następujące ostrzeżenie na temat wszystkich wyeksportowanych klas, które używają klasy ATL CString (znaleziono w atlstr.h):Ostrzeżenie C4251 podczas budowania biblioteki DLL, która eksportuje klasę zawierającą element ATL :: CString

warning C4251: 'Foo :: str_' klasę 'ATL :: CStringT' musi mieć dll interfejs do stosowania przez klientów klasy 'Foo'

Poprawnie deklaruję klasę Foo jako e xported przez __declspec(dllexport). Czy to ostrzeżenie, które mogę bezpiecznie zignorować, czy też robię coś nie tak? Ustawienia projektu DLL są ustawione tak, aby dynamicznie łączyły się z ATL, ale nie wydaje się to mieć żadnego znaczenia.

Na przykład:

#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 
}; 

Wszyscy klienci tego DLL będzie również przy użyciu ATL.

+0

Jeśli jesteś w stanie zapewnić zarówno bibliotekę, a klient jest zbudowany na dokładnie tej samej wersji biblioteki ATL, niż można go zignorować. –

Odpowiedz

15

This thread daje to, co uważam za lepszą odpowiedź, Doug Harrison (VC++ MVP):

[To jest ostrzeżenie] emitowany podczas korzystania niebędącego dllexported klasy X w dllexported klasy Y. Co jest takiego złego? Załóżmy, że Y ma funkcję wbudowaną y_f, która wywołuje funkcję x_f należącą do X, która jest , również nie jest wbudowana. Jeśli y_f jest wstawiony wewnątrz jakiegoś klienta, który nie łączy się statycznie z linkiem X, link nie powiedzie się, , ponieważ x_f nie zostanie znaleziony.

+2

Link został usunięty. – laishiekai

+0

Pokrewne uwagi: http://www.qtforum.org/article/36372/warning-c4251.html –

+0

@WillBickford: Dzięki, pomyślałem, że pierwotna dyskusja już dawno zaginęła. –

5

Here is a thread z dobrą dyskusją na ten temat.

W skrócie, kompilator ostrzega, że ​​w efekcie klasa wyeksportowana nie oddziela interfejsu od implementacji. Jeśli członkowie, o których mowa, nie są dostępni dla klientów, uczyń ich prywatnymi, a #pragma ostrzeżeniem dla tego członka/klasy. Jeśli członkowie są dostępni i wykorzystywani przez klientów, musisz zapewnić pośredni dostęp do członków za pośrednictwem akcesorów i mutatorów.

+3

Więc jeśli ostrzeżone obiekty są już prywatne dla klasy, możemy bezpiecznie zignorować to ostrzeżenie? – meawoppl

1

Zazwyczaj otrzymuję to ostrzeżenie, gdy popełniam głupi błąd podczas budowania biblioteki DLL za pomocą biblioteki wykonawczej Single/Multithreaded zamiast Single/MultithreadedDLL. Możesz to sprawdzić w ustawieniach projektu.