Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1156 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [VISUAL STUDIO 6]Warning bizarre - conseil

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[VISUAL STUDIO 6]Warning bizarre - conseil

n°317780
Joel F
Real men use unique_ptr
Posté le 25-02-2003 à 21:13:24  profilanswer
 

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.

mood
Publicité
Posté le 25-02-2003 à 21:13:24  profilanswer
 

n°317806
LeGreg
Posté le 25-02-2003 à 21:41:19  profilanswer
 

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
n°317808
Willyzekid
Posté le 25-02-2003 à 21:42:41  profilanswer
 

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!!
n°317811
Joel F
Real men use unique_ptr
Posté le 25-02-2003 à 21:48:40  profilanswer
 

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 ?

n°317817
Willyzekid
Posté le 25-02-2003 à 21:55:26  profilanswer
 

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!!
n°317821
Joel F
Real men use unique_ptr
Posté le 25-02-2003 à 21:58:20  profilanswer
 

donc un truc du style  :
 

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


 
ca suffirait ?
 

n°317846
LeGreg
Posté le 25-02-2003 à 22:46:12  profilanswer
 

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
n°318011
YungMakko
Posté le 26-02-2003 à 09:25:40  profilanswer
 

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!

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [VISUAL STUDIO 6]Warning bizarre - conseil

 

Sujets relatifs
Visual Basic : comment enregistrer??[C]Pourquoi ce Warning? une idée?
Besoin d'aide en Visual Basic![Visual C++] Changer la couleur du texte d'un bouton ?
j'aime po AppWizard et ClassWizard de VIsual C++[Visual Studio C++] recherche code pour la comparaison de 2 images
Cherche Delphi 7 Studio d'occaz sur Paris ...[C++]Faire des onglets (Tab Control) en Visual C++
[C++]Utilisation de ADO en VISUAL C++ 
Plus de sujets relatifs à : [VISUAL STUDIO 6]Warning bizarre - conseil


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR