Comment éviter d'inclure deux fois les fichiers d'en-tête? Le problème est que j'inclus ledans MyClass.h , puis j'inclus MyClass.h dans de nombreux fichiers, il inclut donc plusieurs fois et une erreur de redéfinition se produit. Comment empêcher?
J'utilise #pragma une fois au lieu d'inclure des gardes, et je suppose que c'est très bien.
MyClass.h:
// MyClass.h
#pragma once
#include <winsock2.h>
class MyClass
{
// methods
public:
MyClass(unsigned short port);
virtual ~MyClass(void);
};
EDIT: peu d'erreurs que je reçois
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(91) : warning C4005: 'AF_IPX' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(460) : see previous definition of 'AF_IPX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(124) : warning C4005: 'AF_MAX' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(479) : see previous definition of 'AF_MAX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(163) : warning C4005: 'SO_DONTLINGER' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(402) : see previous definition of 'SO_DONTLINGER'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(206) : error C2011: 'sockaddr' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(485) : see declaration of 'sockaddr'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing '}' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing ';' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2059: syntax error : 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C2143: syntax error : missing ';' before '}'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(518) : warning C4005: 'IN_CLASSA' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(287) : see previous definition of 'IN_CLASSA'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(524) : warning C4005: 'IN_CLASSB' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(293) : see previous definition of 'IN_CLASSB'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(530) : warning C4005: 'IN_CLASSC' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(299) : see previous definition of 'IN_CLASSC'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(541) : warning C4005: 'INADDR_ANY' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(304) : see previous definition of 'INADDR_ANY'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(543) : warning C4005: 'INADDR_BROADCAST' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(306) : see previous definition of 'INADDR_BROADCAST'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(577) : error C2011: 'sockaddr_in' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(312) : see declaration of 'sockaddr_in'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(132) : error C2011: 'fd_set' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(68) : see declaration of 'fd_set'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(167) : warning C4005: 'FD_SET' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(102) : see previous definition of 'FD_SET'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(176) : error C2011: 'timeval' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(111) : see declaration of 'timeval'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(232) : error C2011: 'hostent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(167) : see declaration of 'hostent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(245) : error C2011: 'netent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(180) : see declaration of 'netent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(252) : error C2011: 'servent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(187) : see declaration of 'servent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(264) : error C2011: 'protoent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(199) : see declaration of 'protoent'
c++
header
redefinition
akif
la source
la source
Réponses:
Ce problème est causé lors de l'inclusion
<windows.h>
avant<winsock2.h>
. Essayez d'organiser votre liste d'inclusion qui<windows.h>
est incluse après<winsock2.h>
ou définissez d'_WINSOCKAPI_
abord:Voyez aussi ceci .
la source
<winsock2.h>
MSVC2008.<windows.h>
l'inclusion le fait générer des erreurs de compilation identiques à celles que vous avez fournies.#include <winsock2.h> #include <ws2tcpip.h> #include <windows.h>
en ordre et obtenais winsock2, fichier h introuvable. Inclus#define _WINSOCKAPI_
au-dessus de tous les 3 comprend toujours la même erreurComme d'autres l'ont suggéré, le problème est de savoir quand
windows.h
est inclus avantWinSock2.h
. Parce quewindows.h
comprendwinsock.h
. Vous ne pouvez pas utiliser à la foisWinSock2.h
etwinsock.h
.Solutions:
Inclure
WinSock2.h
avantwindows.h
. Dans le cas des en-têtes précompilés, vous devez le résoudre ici. Dans le cas d'un projet simple, c'est facile. Cependant, dans les grands projets (en particulier lors de l'écriture de code portable, sans en-têtes précompilés), cela peut être très difficile, car lorsque votre en-tête avecWinSock2.h
est inclus,windows.h
peut déjà être inclus à partir d'un autre fichier d'en-tête / d'implémentation.Définissez
WIN32_LEAN_AND_MEAN
avantwindows.h
ou à l'échelle du projet. Mais cela exclura de nombreux autres éléments dont vous pourriez avoir besoin et vous devez les inclure vous-même.Définissez
_WINSOCKAPI_
avantwindows.h
ou à l'échelle du projet. Mais lorsque vous incluez,WinSock2.h
vous obtenez un avertissement de redéfinition de macro.Utilisez
windows.h
plutôt queWinSock2.h
quandwinsock.h
est suffisant pour votre projet (dans la plupart des cas, c'est le cas). Cela entraînera probablement un temps de compilation plus long mais résoudra toutes les erreurs / avertissements.la source
WIN32_LEAN_AND_MEAN
était la solution pour moi beaucoup de chars_WINSOCK_
solution: vous ne devriez pas grt d'avertissement de redéfinition de macro si les deux définitions sont identiques. Le bogue commun est que les gens ajoutent une définition au projet sans définir de valeur et s'attendent à une définition vide. Cependant, si vous ajoutez-D_WINSOCK_
à la ligne cmd, il sera défini_WINSOCK_
sur 1. Pour créer une définition vide,-D_WINSOCK_=
doit être passé.#define _WINSOCKAPI_
, vous pouvez également avoir besoin#define _WINSOCK_DEPRECATED_NO_WARNINGS
, selon votre situation.Oh - la laideur de Windows ... L'ordre des inclusions est important ici. Vous devez inclure winsock2.h avant windows.h. Puisque windows.h est probablement inclus à partir de votre en-tête précompilé (stdafx.h), vous devrez inclure winsock2.h à partir de là:
la source
En utilisant des "protections d'en-tête":
la source
J'ai rencontré ce problème en essayant d'extraire un paquet tiers qui incluait apparemment windows.h quelque part dans son désordre d'en-têtes. Définir
_WINSOCKAPI_
au niveau du projet était beaucoup plus facile (pour ne pas dire plus facile à maintenir) que de patauger dans leur soupe et de résoudre le problème.la source
DEFINES += _WINSOCKAPI_
Dans VS 2015, les éléments suivants fonctionneront:
Bien que ce ne soit pas le cas:
la source
J'ai vérifié les inclusions récursives, j'ai repéré les fichiers d'en-tête qui en incluent (récursivement) certains
#include "windows.h"
et#include "Winsock.h"
et j'écris un fichier#include "Winsock2.h"
. dans ces fichiers, j'ai ajouté#include "Winsock2.h"
comme premier inclure.Juste une question de patience, regardez les inclus un par un et établissez cet ordre, d'abord
#include "Winsock2.h"
puis#include "windows.h"
la source
J'ai trouvé ce lien windows.h et winsock2.h qui a une alternative qui a très bien fonctionné pour moi:
J'avais du mal à trouver où le problème se produisait, mais en ajoutant cette #define, j'ai pu construire sans le comprendre.
la source
Je n'utiliserais pas uniquement FILENAME_H mais
J'ai toujours utilisé un guid postfix. Je suis tombé sur une base de code très pauvre il y a quelques années qui avait différents fichiers d'en-tête avec le même nom de fichier et include guard. Les fichiers en question avaient défini une classe du même nom. Si seuls les espaces de noms étaient utilisés. Certains projets ont compilé d'autres non. L'utilisation de gardes uniques faisait partie de la solution pour différencier les en-têtes et leur contenu.
Sous Windows avec Visual Studio, utilisez guidgen.exe, sous Linux uuidgen -t.
la source
J'ai rencontré le même problème et voici ce que j'ai découvert jusqu'à présent:
À partir de ce fragment de sortie -
-Il semble que ws2def.h et winsock.h ont été inclus dans votre solution.
Si vous regardez le fichier ws2def.h, il commence par le commentaire suivant -
Faites attention à la dernière ligne - "Ce fichier ne peut pas être inclus par un module qui inclut également WINSOCK.H"
Essayez toujours de résoudre le problème sans apporter de modifications au code.
Faites-moi savoir si cela a du sens.
la source
Vous devez utiliser la protection d'en-tête.
mettre ces lignes en haut du fichier d'en-tête
et en bas
la source
#pragma once
est basé sur le chemin complet du nom de fichier. Donc, ce que vous avez probablement, c'est qu'il existe deux copies identiques de MyClass.h ou Winsock2.h dans des répertoires différents.la source
#pragma once
est flakey, même sur les compilateurs MS, et n'est pas pris en charge par de nombreux autres compilateurs. Comme beaucoup d'autres personnes l'ont mentionné, utiliser des gardes d'inclusion est la voie à suivre. Ne l'utilisez pas#pragma once
du tout - cela vous facilitera la vie.la source
#pragma once
, le compilateur prend le nom du nœud du fichier d'en-tête comme ID unique. Cela peut échouer si vous avez des liens symboliques ou des jonctions NTFS dans votre arborescence source (plus courant que vous ne le pensez), ou même si vous avez un fichier du même nom dans un autre répertoire d'inclusion système (cela m'est déjà arrivé lorsque j'ai la version 1 et la version 2 de la même bibliothèque installée sur deux systèmes différents incluent des chemins). Conclusion: pour moi, je préfère avoir plus de contrôle et vivre avec des erreurs occasionnelles de wetware, plutôt que de faire confiance à un compilateur pour le faire à ma place.#include gardes est la manière standard de faire cela. #pragma ne l'est pas une fois , ce qui signifie que tous les compilateurs ne le supportent pas.
la source
Dans mon projet (j'utilise VS 2008 SP1) fonctionne la solution suivante:
En tête de fichier:
Classe Cpp:
où #include "winsock2class.h" signifie la classe qui a implémenté winsock2.h:
la source
En fait, j'ai rencontré un problème où j'ai dû définir winsock2.h comme premier include, il semble qu'il ait d'autres problèmes avec les inclusions d'autres packages. J'espère que cela sera utile à quelqu'un qui rencontre le même problème, pas seulement windows.h mais tout inclut.
la source