[VISUAL STUDIO 6]Warning bizarre - conseil

Warning bizarre - conseil [VISUAL STUDIO 6] - C++ - Programmation

Marsh Posté le 25-02-2003 à 21:13:24    

Code :
  1. warning C4251: 'mMappingName' : class 'std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' needs to have dll-interface to be used by clients of class 'MemoryFile'


 
... le tout en compilant cette classe
 

Code :
  1. #include <string>
  2. extern "C" class __declspec(dllexport) MemoryFile
  3. {
  4. public:
  5.   MemoryFile();
  6. virtual ~MemoryFile();
  7.         // Autres methodes ...
  8. private:
  9.         std::string  mMappingName;
  10. };


 
... ca compile et ca link mais j'aime pas les warning.

Reply

Marsh Posté le 25-02-2003 à 21:13:24   

Reply

Marsh Posté le 25-02-2003 à 21:41:19    

La premiere grosse erreur c'est que tu declares extern "C"
une classe alors que les classes ca n'existe qu'en C++.
 
Deuxieme erreur, si j'etais toi je remplacerais
le __declspec(dllexport) par une macro
qui dans le cas d'un export vaut __declspec(dllexport)
et dans le cas d'un import vaut __declspec(dllimport).
 
Troisieme erreur et la cause sans doute de ton warning.
mMappingName est un membre de ta classe MemoryFile qui est exportee dans une dll, la regle veut que std::string soit egalement un type exporte par la DLL.
 
Donc tu dois au prealable de toute utilisation de std::string
faire une instanciation explicite de basic_string<char>
en la declarant:  

Code :
  1. template class __declspec(dllexport) std::basic_string<char>;


 
et lors de l'importation:

Code :
  1. extern template classe __declspec(dllimport) std::basic_string<char>;


 
Et la encore je te conseille d'utiliser des macros suivant que tu importes ou que tu exportes.
 
Mais la je peux te dire que tu es dans la merde.
Parce que si l'utilisateur de ta DLL et de l'objet MemoryFile
se met en tête d'utiliser des string dans son programme, il devra alors explicitement importer pareil les basic_string<char> avant toute utilisation explicite de string (en esperant qu'il n'utilise pas une librairie statique ou dynamique qui utilise egalement les std::string a leur maniere et qu'il ne peut pas modifier).
 
Conseil: si tu peux l'eviter, renomme ton string en n'importe quoi, et cache le a l'export surtout si c'est pour une utilisation privee.
 
..
 
petit bemol: en fait sous VC6 ce warning n'empeche pas la compilation donc tu peux laisser comme ca a tes risques et perils. par contre sous VC7 cela est devenu une erreur et  
donc tu es oblige d'adopter la regle decrite ci-dessus.
(j'imagine que les gars de Microsoft ont juste voulu empecher
les comportements ambigus dans la nouvelle version du compilateur)
 
LeGreg


---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 25-02-2003 à 21:42:41    

Ben tu n'as pas de chance, tu vas devoir vivre avec celui là.  
 
Je pense pas que tu puisse y faire grand chose...Perso j'ai pas trouvé de solution (les classes de bases ne sont pas exporté -> donc erreur?)
 
Ou plutôt si: #pragma warning (disable : 4251) :D
(pour le temps de la déclaration)


---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 25-02-2003 à 21:48:40    

legreg a écrit :

La premiere grosse erreur c'est que tu declares extern "C"
une classe alors que les classes ca n'existe qu'en C++.


 
oops erreur d etapage. Corrigée :)
 

legreg a écrit :


Deuxieme erreur, si j'etais toi je remplacerais
le __declspec(dllexport) par une macro
qui dans le cas d'un export vaut __declspec(dllexport)
et dans le cas d'un import vaut __declspec(dllimport).


 
Fait aussi mais enlevée pour souci de clarté
 
 

legreg a écrit :


Troisieme erreur et la cause sans doute de ton warning.
mMappingName est un membre de ta classe MemoryFile qui est exportee dans une dll, la regle veut que std::string soit egalement un type exporte par la DLL.
 
...
 
Mais la je peux te dire que tu es dans la merde.
Parce que si l'utilisateur de ta DLL et de l'objet MemoryFile
se met en tête d'utiliser des string dans son programme, il devra alors explicitement importer pareil les basic_string<char> avant toute utilisation explicite de string (en esperant qu'il n'utilise pas une librairie statique ou dynamique qui utilise egalement les std::string a leur maniere et qu'il ne peut pas modifier).
 
Conseil: si tu peux l'eviter, renomme ton string en n'importe quoi, et cache le a l'export surtout si c'est pour une utilisation privee.


 
Pas moyen d'utiliser std::string alors ? ca me fait iech, pas envie de bidouiller du char* :(
Que faire ?

Reply

Marsh Posté le 25-02-2003 à 21:55:26    

legreg a écrit :

La premiere grosse erreur c'est que tu declares extern "C"
une classe alors que les classes ca n'existe qu'en C++.
 
Deuxieme erreur, si j'etais toi je remplacerais
le __declspec(dllexport) par une macro
qui dans le cas d'un export vaut __declspec(dllexport)
et dans le cas d'un import vaut __declspec(dllimport).
 
Troisieme erreur et la cause sans doute de ton warning.
mMappingName est un membre de ta classe MemoryFile qui est exportee dans une dll, la regle veut que std::string soit egalement un type exporte par la DLL.
 
Donc tu dois au prealable de toute utilisation de std::string
faire une instanciation explicite de basic_string<char>
en la declarant:  

Code :
  1. template class __declspec(dllexport) std::basic_string<char>;


 
et lors de l'importation:

Code :
  1. extern template classe __declspec(dllimport) std::basic_string<char>;


 
Et la encore je te conseille d'utiliser des macros suivant que tu importes ou que tu exportes.
 
Mais la je peux te dire que tu es dans la merde.
Parce que si l'utilisateur de ta DLL et de l'objet MemoryFile
se met en tête d'utiliser des string dans son programme, il devra alors explicitement importer pareil les basic_string<char> avant toute utilisation explicite de string (en esperant qu'il n'utilise pas une librairie statique ou dynamique qui utilise egalement les std::string a leur maniere et qu'il ne peut pas modifier).
 
Conseil: si tu peux l'eviter, renomme ton string en n'importe quoi, et cache le a l'export surtout si c'est pour une utilisation privee.
 
..
 
petit bemol: en fait sous VC6 ce warning n'empeche pas la compilation donc tu peux laisser comme ca a tes risques et perils. par contre sous VC7 cela est devenu une erreur et  
donc tu es oblige d'adopter la regle decrite ci-dessus.
(j'imagine que les gars de Microsoft ont juste voulu empecher
les comportements ambigus dans la nouvelle version du compilateur)
 
LeGreg


 
Marrant, c'est ce que j'ai toujours fait pour les classes genre Vector où l'instanciation est explicite mais jamais pensé à le faire pour string.
En passant il faut toujours faire un #pragma warning (disable : 4231) :D
 
Joel, c'est pas si compliqué. Par exemple (ca vient du fichier surlequel je bosse...c'est un h inclu dans la plupart des fichiers de la dll):
 

Code :
  1. typedef Surface*        ImagePtr;
  2. typedef vector< ImagePtr >  FrameList;
  3. #ifdef WIN32
  4.    #ifdef DODI_EXPORTS
  5.       #define DODI_API __declspec(dllexport)
  6.       #define EXPIMP_TEMPLATE
  7.    #else
  8.       #define DODI_API __declspec(dllimport)
  9.       #define EXPIMP_TEMPLATE extern
  10.    #endif
  11.    #pragma warning (disable : 4231)
  12.    EXPIMP_TEMPLATE template struct DODI_API std::pair< float, float >;
  13.    EXPIMP_TEMPLATE template struct DODI_API std::pair< int, int >;
  14.    EXPIMP_TEMPLATE template class DODI_API std::vector< ImagePtr >;
  15. #endif


Message édité par Willyzekid le 25-02-2003 à 21:58:35

---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 25-02-2003 à 21:58:20    

donc un truc du style  :
 

Code :
  1. EXPIMP_TEMPLATE template struct JOEL_API std::basic_string< char >;


 
ca suffirait ?
 

Reply

Marsh Posté le 25-02-2003 à 22:46:12    

Joel F a écrit :

donc un truc du style  :
 

Code :
  1. EXPIMP_TEMPLATE template struct JOEL_API std::basic_string< char >;


 
ca suffirait ?


 
yep.
Tu noteras qu'il faut que cette instanciation explicite soit faite avant toute reference a std::string
Donc a documenter si tu ne veux pas que l'utilisateur se prenne des erreurs inexplicables dans la figure..
 
Et prier aussi pour que l'utilisateur n'utilise pas de librairie qui utilise des std::string dans ses headers.
 
LeGreg


---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 26-02-2003 à 09:25:40    

Si il y a moyen de résoudre ce problème:
 
http://support.microsoft.com/defau [...] us;q168958
 
 
C'est juste un peu chiant...  ;)


---------------
In tartiflette, we trust!
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed