2010-01-25 6 views
13

Io sono la conversione di una libreria statica ATL-based per una DLL e sto ottenendo il seguente avviso su tutte le classi esportate che utilizzano l'ATL CString di classe (trovato in atlstr.h):Attenzione C4251 quando si costruisce una DLL che esporta una classe contenente un ATL :: CString membro

C4251 avviso: 'Foo :: str_': classe 'ATL :: CStringT' ha bisogno di avere dll-interfaccia da utilizzare dai clienti di classe 'Foo'

Dichiaro correttamente la classe Foo come e xportato tramite __declspec(dllexport). È un avvertimento che posso tranquillamente ignorare o sto facendo qualcosa di sbagliato? Le impostazioni del progetto DLL sono impostate per il collegamento dinamico con ATL, ma ciò non sembra fare alcuna differenza.

Ad esempio:

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

Tutti i clienti di questa DLL saranno anche utilizzando ATL.

+0

Se siete in grado di garantire sia la biblioteca e il cliente è costruita contro la stessa versione della libreria ATL, di quanto si può ignorarlo. –

risposta

15

This thread dà quello che io considero una risposta migliore, da Doug Harrison (VC++ MVP):

[Questo avviso viene] emesso quando si utilizza una classe non dllexported X in un dllexported Y. classe Cosa c'è di così bello ? Bene, supponiamo che Y abbia una funzione in linea y_f che chiama una funzione x_f appartenente a X che è non in linea. Se y_f è in linea all'interno di un client che non collega link statico X, il collegamento fallirà, perché x_f non sarà trovato.

+2

Il collegamento è stato rimosso. – laishiekai

+0

citazione correlati: http://www.qtforum.org/article/36372/warning-c4251.html –

+0

@WillBickford: Grazie, ho pensato che la discussione originale è stato perso da tempo .. –

5

Here is a thread con una buona discussione di questo.

In breve, il compilatore ti avverte che, in effetti, la tua classe esportata non separa l'interfaccia dall'implementazione. Se i membri in questione non sono accessibili ai client, renderli privati ​​e #pragma via l'avviso per quel membro/classe. Se i membri sono accessibili e utilizzati dai clienti, sarà necessario fornire un accesso indiretto ai membri tramite accessor e mutator.

+3

Quindi, se gli oggetti avvertiti sono già privati ​​della classe, possiamo tranquillamente ignorare questo avviso? – meawoppl

1

Generalmente ricevo questo avviso quando faccio lo stupido errore di compilare la DLL con la libreria di runtime Single/Multithreaded invece di Single/MultithreadedDLL. Potresti volerlo controllare nelle impostazioni del tuo progetto.