Файлы заголовков C ++ Redefinition (winsock2.h)

Как я могу предотвратить включение файлов заголовков дважды? Проблема в том, что я включаю в MyClass.h, а затем я включаю MyClass.h во многие файлы, поэтому он включает в себя несколько раз и возникает ошибка переопределения. Как предотвратить?

Я использую #pragma один раз вместо включения охранников, и я думаю, это нормально.

MyClass.h:

// MyClass.h #pragma once #include  class MyClass { // methods public: MyClass(unsigned short port); virtual ~MyClass(void); }; 

EDIT: Мало ошибок, которые я получаю

 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' 

Эта проблема возникает при включении до . Попробуйте упорядочить список включений, который включен после или сначала определите _WINSOCKAPI_ :

 #define _WINSOCKAPI_ // stops windows.h including winsock.h #include  // ... #include "MyClass.h" // Which includes  

См. Также это .

Как и другие, проблема заключается в том, что windows.h включен перед WinSock2.h . Потому что windows.h включает winsock.h . Вы не можете использовать WinSock2.h и winsock.h .

Решения:

  • Включите WinSock2.h перед windows.h . В случае предварительно скомпилированных заголовков вы должны его решить. В случае простого проекта это легко. Однако в больших проектах (особенно при написании переносного кода без предварительно скомпилированных заголовков) это может быть очень сложно, потому что когда заголовок с WinSock2.h включен, windows.h может быть уже включен из другого файла заголовка / реализации.

  • Определите WIN32_LEAN_AND_MEAN перед WIN32_LEAN_AND_MEAN или по всему проекту. Но это исключает многие другие вещи, которые могут вам понадобиться, и вы должны включить их сами.

  • Определите _WINSOCKAPI_ перед _WINSOCKAPI_ или по всему проекту. Но когда вы включаете WinSock2.h вы получаете предупреждение о переопределении макросов.

  • Используйте windows.h вместо WinSock2.h когда winsock.h достаточно для вашего проекта (в большинстве случаев это). Вероятно, это приведет к более длительному времени компиляции, но решает любые ошибки / предупреждения.

Используя «защита заголовка»:

 #ifndef MYCLASS_H #define MYCLASS_H // This is unnecessary, see comments. //#pragma once // MyClass.h #include  class MyClass { // methods public: MyClass(unsigned short port); virtual ~MyClass(void); }; #endif 

О – уродство Windows … Здесь важны порядок включений. Вам нужно включить winsock2.h перед windows.h. Поскольку windows.h, вероятно, включен из вашего предварительно скомпилированного заголовка (stdafx.h), вам нужно будет включить winsock2.h оттуда:

 #include  #include  

Я столкнулся с этой проблемой, пытаясь вытащить сторонний пакет, который, по-видимому, включал windows.h где-то в беспорядке заголовков. Определение _WINSOCKAPI_ на уровне проекта было намного проще (не говоря уже о более ремонтопригодном), чем прохождение через их суп и устранение проблем.

Я бы не использовал только FILENAME_H, но

 #ifndef FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD #define FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD //code stuff #endif // FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD 

Я всегда использовал postfix guid. Несколько лет назад я столкнулся с очень плохой базой кода, которая имела разные заголовочные файлы с тем же именем файла и включала защиту. В рассматриваемых файлах был определен class с тем же именем. Если использовались только пространства имен. Некоторые проекты, скомпилированные, некоторые не сделали. Использование уникальных охранников было частью решения при разграничении заголовков и их содержимого.

В Windows с Visual Studio используйте guidgen.exe, на Linux uuidgen -t.

Я нашел эту ссылку windows.h и winsock2.h, у которой есть альтернатива, которая отлично поработала для меня:

 #define _WINSOCKAPI_ // stops windows.h including winsock.h #include  #include  

У меня возникли проблемы с поиском, где возникла проблема, но добавив, что #define я смог построить, не выясняя это.

Я столкнулся с той же проблемой, и вот что я обнаружил до сих пор:

Из этого выходного fragmentа –

 c: \ program files \ microsoft sdks \ windows \ v6.0a \ include \ ws2def.h (91): предупреждение C4005: 'AF_IPX': переопределение макросов
 c: \ program files \ microsoft sdks \ windows \ v6.0a \ include \ winsock.h (460): см. предыдущее определение 'AF_IPX'

-Похоже, что и ws2def.h и winsock.h были включены в ваше решение.

Если вы посмотрите файл ws2def.h, он начинается со следующего комментария –

 /*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: ws2def.h Abstract: This file contains the core definitions for the Winsock2 specification that can be used by both user-mode and kernel mode modules. This file is included in WINSOCK2.H. User mode applications should include WINSOCK2.H rather than including this file directly. This file can not be included by a module that also includes WINSOCK.H. Environment: user mode or kernel mode --*/ 

Обратите внимание на последнюю строку – «Этот файл не может быть включен модулем, который также включает WINSOCK.H»

Все еще пытаюсь исправить проблему без внесения изменений в код.

Дайте мне знать, если это имеет смысл.

Я проверил, что рекурсивный включает, я заметил файлы заголовков, которые include (рекурсивно) некоторые #include "windows.h" и “#include” Winsock.h ” and write a #include” Winsock2.h ” . in this files, i added #include “Winsock2.h” `в качестве первого включить.

Просто вопрос терпения, посмотрите, включает один за другим и устанавливает этот порядок, сначала #include "Winsock2.h" затем #include "windows.h"

Вы должны использовать заголовок.

поместите эту строку в верхнюю часть файла заголовка

 #ifndef PATH_FILENAME_H #define PATH_FILENAME_H 

и внизу

 #endif 

#pragma once основывается на полном пути имени файла. Итак, у вас есть две идентичные копии MyClass.h или Winsock2.h в разных каталогах.

В VS 2015 будет работать следующее:

 #define _WINSOCKAPI_ 

В то время как следующее не будет:

 #define WIN32_LEAN_AND_MEAN 

#pragma once чешуйчатый, даже на компиляторах MS, и не поддерживается многими другими компиляторами. Как и многие другие люди, использование охранников – это путь. Не используйте #pragma once – это сделает вашу жизнь намного проще.

#include защита – это стандартный способ сделать это. #pragma once is not, что означает, что не все компиляторы поддерживают его.

В моем проекте (я использую VS 2008 SP1) работает следующее решение:

Заголовок файла:

 //myclass.h #pragma once #define _WINSOCKAPI_ #include  

Класс Cpp:

 //myclass.cpp #include "Util.h" #include "winsock2class.h" #pragma comment(lib, "Ws2_32.lib") 

где #include “winsock2class.h” означает class, который реализовал winsock2.h:

 //winsock2class.h #include  #include  #pragma comment(lib, "Ws2_32.lib") 
Interesting Posts

Как повернуть файл видео (MOV) в Windows?

Dropbox говорит, что он не может синхронизировать файл из-за ограничений пространства

SLF4J: путь classа содержит несколько привязок SLF4J

.net реализация bcrypt

Как получить версию GCC, используемую для компиляции данного исполняемого файла ELF?

Как получить bash для автоматического обновления кеша местоположений программ?

получить строку с разделителями-запятыми из строк

Как добавить вид программы в RelativeLayout?

Как я могу игнорировать свойство при сериализации с помощью DataContractSerializer?

Как определить перечисляемый тип (enum) в C?

Сделать IMAP-электронную почту, которая читается на одном компьютере, показываться как непрочитанная на другой машине

Загрузите файл jQuery ajax в asp.net mvc

Eclipse и Windows newlines

Какие ресурсы для начала работы в операционной системе?

Установка цвета страницы без цвета при отправке или ответе в Outlook 2010

Давайте будем гением компьютера.