2010-01-25 10 views
13

Je convertis une bibliothèque statique ATL en DLL et obtiens l'avertissement suivant sur toutes les classes exportées utilisant la classe ATL CString (trouvée en atlstr.h):Avertissement C4251 lors de la construction d'une DLL exportant une classe contenant un membre ATL :: CString

avertissement C4251: 'Foo :: str_': class 'ATL :: CStringT' doit avoir dll-interface à utiliser par les clients de la classe 'Foo'

Je déclare correctement la classe Foo comme e xporté via __declspec(dllexport). Est-ce un avertissement que je peux ignorer ou est-ce que je fais quelque chose de mal? Les paramètres du projet DLL sont configurés pour un lien dynamique avec ATL, mais cela ne semble pas faire de différence.

Par exemple:

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

Tous les clients de cette DLL seront également en utilisant ATL.

+0

Si vous êtes en mesure d'assurer à la fois la bibliothèque et le client est Adossé à la même version exacte de la bibliothèque ATL, que vous ne pouvez l'ignorer. –

Répondre

15

This thread donne ce que je considère une meilleure réponse, par Doug Harrison (VC++ MVP):

[Cet avertissement est] émis lorsque vous utilisez une classe non-dllexported X dans une classe dllexported Y. Quel est le problème à ce sujet? Eh bien, supposons que Y a une fonction inline qui appelle une fonction appartenant à X qui est pas aussi en ligne. Si y_f est en ligne à l'intérieur d'un client qui n'a pas le lien statique , le lien échouera, car x_f ne sera pas trouvé.

+2

Le lien est supprimé. – laishiekai

+0

citation connexes: http://www.qtforum.org/article/36372/warning-c4251.html –

+0

@WillBickford: Merci, je pensais que la discussion originale a été perdue depuis longtemps .. –

5

Here is a thread avec une bonne discussion de cela. En résumé, le compilateur vous avertit que, en réalité, votre classe exportée ne sépare pas l'interface de l'implémentation. Si les membres en question ne sont pas accessibles aux clients, rendez-les privés et #pragma l'avertissement pour ce membre/classe. Si les membres sont accessibles et utilisés par les clients, vous devrez fournir un accès indirect aux membres via des accesseurs et des mutateurs.

+3

Donc, si les objets avertis sont déjà privés à la classe, nous pouvons ignorer cet avertissement en toute sécurité? – meawoppl

1

Je reçois généralement cet avertissement lorsque je fais l'erreur stupide de construire la DLL avec la bibliothèque d'exécution Single/Multithreaded au lieu de Single/MultithreadedDLL. Vous voudrez peut-être vérifier cela dans les paramètres de votre projet.