C++重定义头文件(winsock2.h)

aki*_*kif 133 c++ header redefinition

如何防止包含两次头文件?问题是我包括了MyClass.h中然后我将MyClass.h包含在许多文件中,因此它包含多次并发生重定义错误.怎么预防?

我正在使用#pragma而不是包含警卫,我想这很好.

MyClass.h:

// MyClass.h
#pragma once

#include <winsock2.h>

class MyClass
{

// methods
public:
 MyClass(unsigned short port);
 virtual ~MyClass(void);
};
Run Code Online (Sandbox Code Playgroud)

编辑:我得到的错误很少

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'
Run Code Online (Sandbox Code Playgroud)

pin*_*33n 219

包含<windows.h>之前包含此问题<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>
Run Code Online (Sandbox Code Playgroud)

另请参见.

  • 对我来说,你的代码在MSVC2008中仅用`<winsock2.h>`编译好.`<windows.h>`include使它产生与你提供的相同的编译错误. (2认同)

Pav*_*iak 73

正如其他人所说,问题在于windows.h之前是否包括在内WinSock2.h.因为windows.h包括winsock.h.你不能同时使用WinSock2.hwinsock.h.

解决方案:

  • 包括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足够你的项目(在大多数情况下是).这可能会导致更长的编译时间,但可以解决任何错误/警告.

  • `WIN32_LEAN_AND_MEAN`是我坦克的解决方案 (14认同)

Dan*_*ull 15

哦 - Windows的丑陋......包含的顺序在这里很重要.你需要在windows.h之前包含winsock2.h.由于windows.h可能包含在预编译头文件(stdafx.h)中,因此您需要包含winsock2.h:

#include <winsock2.h>
#include <windows.h>
Run Code Online (Sandbox Code Playgroud)


Dev*_*lar 14

通过使用"标题保护":

#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
Run Code Online (Sandbox Code Playgroud)

  • 我想我错了(现在有4个赞成),但是我觉得使用包含警卫就像pragma一样,你把它们都放在一边吗? (2认同)
  • @Angelov:是的,这就是我所说的它们是相同的东西。问题不在于我的头文件,但我认为 &lt;winsock2.h&gt; 本身没有头保护,或者可能是其他东西。 (2认同)

kir*_*off 7

我检查递归包括,我看到的头文件,其中包括(递归地)一些#include "windows.h"#include "Winsock.h"和写#include "Winsock2.h"。在这个文件中,我添加#include "Winsock2.h"为第一个包含。

耐心一点,一一查看include并建立这个顺序,先 #include "Winsock2.h"然后#include "windows.h"


Yau*_*aur 6

当我试图拉出第三方软件包时,我遇到了这个问题,这个软件包显然包含了某些东西,其中有一些标题._WINSOCKAPI_在项目层面定义比趟过汤和修复有问题的包括更容易(更不用说更易于维护).

  • 在 Qt 上,在 .pro 文件中,它看起来像这样:`DEFINES += _WINSOCKAPI_` (2认同)

小智 5

我找到了此链接windows.h和winsock2.h,它对我来说很有用:

#define _WINSOCKAPI_    // stops windows.h including winsock.h
#include <windows.h>
#include <winsock2.h>
Run Code Online (Sandbox Code Playgroud)

我在查找问题发生的位置时遇到了麻烦,但是通过添加#define,我能够在不弄清楚问题的情况下进行构建。


小智 5

在VS 2015中,以下将起作用:

#define _WINSOCKAPI_
Run Code Online (Sandbox Code Playgroud)

虽然以下内容不会:

#define WIN32_LEAN_AND_MEAN
Run Code Online (Sandbox Code Playgroud)


ntc*_*ong 1

您应该使用标头保护。

将这些行放在头文件的顶部

#ifndef PATH_FILENAME_H
#define PATH_FILENAME_H
Run Code Online (Sandbox Code Playgroud)

并在底部

#endif
Run Code Online (Sandbox Code Playgroud)

  • #pragma Once 是非标准的,据我所知 (2认同)