C++ 重定义头文件 (winsock2.h)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1372480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Redefinition Header Files (winsock2.h)
提问by akif
How do I prevent from including header files twice? The problem is I'm including the in MyClass.hand then I'm including MyClass.hin many files, so it includes multiple times and redefinition error occurs. How to prevent?
如何防止两次包含头文件?问题是我包括在MyClass.h 中,然后我在许多文件中包含MyClass.h,因此它包含多次并发生重新定义错误。如何预防?
I'm using #pragma once instead of include guards, and I guess that's fine.
我使用 #pragma once 而不是包含守卫,我想这很好。
MyClass.h:
我的类.h:
// MyClass.h
#pragma once
#include <winsock2.h>
class MyClass
{
// methods
public:
MyClass(unsigned short port);
virtual ~MyClass(void);
};
EDIT:Few of the errors I'm getting
编辑:我遇到的错误很少
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'
回答by pingw33n
This problem is caused when including <windows.h>
before <winsock2.h>
. Try arrange your include list that <windows.h>
is included after <winsock2.h>
or define _WINSOCKAPI_
first:
这个问题是在包含<windows.h>
before时引起的<winsock2.h>
。尝试排列<windows.h>
包含在之后<winsock2.h>
或_WINSOCKAPI_
首先定义的包含列表:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include <windows.h>
// ...
#include "MyClass.h" // Which includes <winsock2.h>
See also this.
另请参见本。
回答by Pavel Machyniak
As others suggested, the problem is when windows.h
is included before WinSock2.h
. Because windows.h
includes winsock.h
. You can not use both WinSock2.h
and winsock.h
.
正如其他人所建议的,问题是 whenwindows.h
包含 before WinSock2.h
。因为windows.h
包括winsock.h
. WinSock2.h
和不能同时使用winsock.h
。
Solutions:
解决方案:
Include
WinSock2.h
beforewindows.h
. In the case of precompiled headers, you should solve it there. In the case of simple project, it is easy. However in big projects (especially when writing portable code, without precompiled headers) it can be very hard, because when your header withWinSock2.h
is included,windows.h
can be already included from some other header/implementation file.Define
WIN32_LEAN_AND_MEAN
beforewindows.h
or project wide. But it will exclude many other stuff you may need and you should include it by your own.Define
_WINSOCKAPI_
beforewindows.h
or project wide. But when you includeWinSock2.h
you get macro redefinition warning.Use
windows.h
instead ofWinSock2.h
whenwinsock.h
is enough for your project (in most cases it is). This will probably result in longer compilation time but solves any errors/warnings.
包括
WinSock2.h
之前windows.h
。在预编译头的情况下,您应该在那里解决它。在简单项目的情况下,这很容易。然而,在大型项目中(尤其是在编写可移植代码时,没有预编译头文件时)可能非常困难,因为当WinSock2.h
包含头文件时,windows.h
可能已经从其他头文件/实现文件中包含了。WIN32_LEAN_AND_MEAN
在之前windows.h
或项目范围内定义。但是它会排除您可能需要的许多其他东西,您应该自己包含它。_WINSOCKAPI_
在之前windows.h
或项目范围内定义。但是当您包含时,您WinSock2.h
会收到宏重定义警告。使用
windows.h
而不是WinSock2.h
何时winsock.h
对您的项目就足够了(在大多数情况下是这样)。这可能会导致更长的编译时间,但可以解决任何错误/警告。
回答by Daniel Paull
Oh - the ugliness of Windows... Order of includes are important here. You need to include winsock2.h before windows.h. Since windows.h is probably included from your precompiled header (stdafx.h), you will need to include winsock2.h from there:
哦 - Windows 的丑陋...这里的包含顺序很重要。您需要在 windows.h 之前包含 winsock2.h。由于 windows.h 可能包含在您的预编译头文件 (stdafx.h) 中,因此您需要从那里包含 winsock2.h:
#include <winsock2.h>
#include <windows.h>
回答by DevSolar
By using "header guards":
通过使用“标题守卫”:
#ifndef MYCLASS_H
#define MYCLASS_H
// This is unnecessary, see comments.
//#pragma once
// MyClass.h
#include <winsock2.h>
class MyClass
{
// methods
public:
MyClass(unsigned short port);
virtual ~MyClass(void);
};
#endif
回答by MariuszW
In VS 2015, the following will work:
在 VS 2015 中,以下将起作用:
#define _WINSOCKAPI_
While the following won't:
虽然以下不会:
#define WIN32_LEAN_AND_MEAN
回答by Yaur
I ran into this problem when trying to pull a third party package which was apparently including windows.h somewhere in it's mess of headers. Defining _WINSOCKAPI_
at the project level was much easier (not to mention more maintainable) than wading through their soup and fixing the problematic include.
我在尝试拉出一个第三方包时遇到了这个问题,该包显然包含 windows.h 的某个地方,在它的头混乱中。_WINSOCKAPI_
在项目级别进行定义比在他们的汤中艰难地解决问题包括更容易(更不用说更易于维护了)。
回答by kiriloff
I checked the recursive includes, I spotted the header files which include (recursively) some #include "windows.h"
and #include "Winsock.h"
and write a #include "Winsock2.h"
. in this files, i added #include "Winsock2.h"
as the first include.
我检查递归包括,我看到的头文件,其中包括(递归地)一些#include "windows.h"
和#include "Winsock.h"
和写#include "Winsock2.h"
。在这个文件中,我添加#include "Winsock2.h"
为第一个包含。
Just a matter of patience, look at includes one by one and establish this order, first #include "Winsock2.h"
then #include "windows.h"
耐心一点,一一查看include并建立这个顺序,先 #include "Winsock2.h"
然后#include "windows.h"
回答by Benjamin Herreid
I found this link windows.h and winsock2.hwhich has an alternative that worked great for me:
我发现这个链接windows.h 和 winsock2.h有一个对我有用的替代方法:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include <windows.h>
#include <winsock2.h>
I was having trouble finding where the issue occurred but by adding that #define I was able to build without figuring it out.
我无法找到问题发生的位置,但是通过添加#define,我能够在不弄清楚的情况下进行构建。
回答by Shailesh Tainwala
I've run into the same issue and here is what I have discovered so far:
我遇到了同样的问题,这是我迄今为止发现的:
From this output fragment -
从这个输出片段 -
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'
-It appears that both ws2def.h and winsock.h have been included in your solution.
- 您的解决方案中似乎已包含 ws2def.h 和 winsock.h。
If you look at the file ws2def.h it starts with the following comment -
如果您查看文件 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
--*/
Pay attention to the last line - "This file can not be included by a module that also includes WINSOCK.H"
注意最后一行——“这个文件不能被同样包含 WINSOCK.H 的模块包含”
Still trying to rectify the problem without making changes to the code.
仍在尝试在不更改代码的情况下纠正问题。
Let me know if this makes sense.
让我知道这是否有意义。
回答by Sam
I wouldn't use just FILENAME_H but
我不会只使用 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
I have always used a postfix guid. I came across a very poor code base some years ago that had different header files with the same file name and include guard. The files in question had defined a class with the same name. If only namespaces were used. Some projects compiled some didn't. Using unique guards was a part of the solution in differentiating headers and their contents.
我一直使用 postfix guid。几年前,我遇到了一个非常糟糕的代码库,其中包含具有相同文件名和包含保护的不同头文件。有问题的文件定义了一个同名的类。如果只使用命名空间。有些项目编译了一些没有。使用独特的守卫是区分标题及其内容的解决方案的一部分。
On Windows with Visual Studio use guidgen.exe, on Linux uuidgen -t.
在带有 Visual Studio 的 Windows 上使用 guidgen.exe,在 Linux 上使用 uuidgen -t。