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

C++ C++;重新定义头文件(winsock2.h),c++,header,redefinition,C++,Header,Redefinition,如何防止头文件包含两次?问题是我将包含在MyClass.h中,然后我将MyClass.h包含在许多文件中,因此它包含多次,并出现重新定义错误。如何预防 我用了一次“pragma”而不是“include guard”,我想这没关系 MyClass.h: // MyClass.h #pragma once #include <winsock2.h> class MyClass { // methods public: MyClass(unsigned short port);

如何防止头文件包含两次?问题是我将包含在MyClass.h中,然后我将MyClass.h包含在许多文件中,因此它包含多次,并出现重新定义错误。如何预防

我用了一次“pragma”而不是“include guard”,我想这没关系

MyClass.h:

// MyClass.h
#pragma once

#include <winsock2.h>

class MyClass
{

// methods
public:
 MyClass(unsigned short port);
 virtual ~MyClass(void);
};
通过使用“收割台防护装置”:

\ifndef MYCLASS\u H
#定义MYCLASS_H
//这是不必要的,请参见注释。
//#布拉格语一次
//MyClass.h
#包括
类MyClass
{
//方法
公众:
MyClass(无符号短端口);
虚拟~MyClass(void);
};
#恩迪夫

您应该使用收割台护罩

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

#ifndef PATH_FILENAME_H
#define PATH_FILENAME_H
在底部

#endif

#pragma once
即使在MS编译器上也很脆弱,许多其他编译器不支持它。正如许多其他人所提到的,使用include-guard是一条可行之路。不要一次使用pragma,这会让你的生活更轻松。

\pragma一次
基于文件名的完整路径。因此,您可能有两个相同的MyClass.h或Winsock2.h副本,位于不同的目录中。

是执行此操作的标准方法。不是,这意味着并非所有编译器都支持它。

之前包含
时会导致此问题。请尝试将
包含在
之后的包含列表安排好,或先定义
\u WINSOCKAPI\u

#define _WINSOCKAPI_    // stops windows.h including winsock.h
#include <windows.h>
// ...
#include "MyClass.h"    // Which includes <winsock2.h>
#定义WINSOCKAPI//停止windows.h,包括winsock.h
#包括
// ...
#包括“MyClass.h”//其中包括

另请参见。

我不会只使用文件名 但是

我一直使用后缀guid。几年前,我遇到了一个非常糟糕的代码库,它有不同的头文件,具有相同的文件名,并且包含guard。有问题的文件定义了一个同名的类。如果只使用名称空间就好了。一些项目编译了一些没有。使用独特的保护是区分标题及其内容的解决方案的一部分


在使用Visual Studio的Windows上使用guidgen.exe,在Linux uuidgen-t上使用guidgen.exe。

我在尝试拉取第三方软件包时遇到了这个问题,该软件包的头文件中显然包含了Windows.h。在项目级别定义
\uWinsockapi
比费力地解决问题要容易得多(更不用说更易于维护)。

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

#include <winsock2.h>
#include <windows.h>
#包括
#包括
我发现这个链接有一个非常适合我的替代方案:

#define _WINSOCKAPI_    // stops windows.h including winsock.h
#include <windows.h>
#include <winsock2.h>
#定义WINSOCKAPI//停止windows.h,包括winsock.h
#包括
#包括

我很难找到问题发生的地方,但是通过添加define,我可以在没有弄清楚的情况下构建它

正如其他人所建议的,问题在于
WinSock2.h
之前包含
windows.h
时。因为
windows.h
包括
winsock.h
。不能同时使用
WinSock2.h
winsock.h

解决方案:

  • windows.h
    之前包括
    WinSock2.h
    。对于预编译头,您应该在那里解决它。对于简单的项目,这很容易。然而,在大型项目中(尤其是在编写可移植代码时,没有预编译头),这可能非常困难,因为当包含带有
    WinSock2.h
    的头时,
    windows.h
    可以从其他头/实现文件中包含


  • windows.h
    或项目范围之前定义
    WIN32\u LEAN\u和\u MEAN
    。但它会排除你可能需要的许多其他东西,你应该自己把它包括进去

  • windows.h
    或项目范围之前定义
    \u WINSOCKAPI
    。但当您包含
    WinSock2.h
    时,会收到宏重新定义警告

  • winsock.h
    对您的项目足够时(在大多数情况下),请使用
    windows.h
    而不是
    WinSock2.h
    。这可能会导致更长的编译时间,但可以解决任何错误/警告


我遇到了同样的问题,以下是我迄今为止的发现:

从这个输出片段-

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' 请注意最后一行-“此文件不能被包含WINSOCK.H的模块包含”

仍然试图在不更改代码的情况下纠正问题


让我知道这是否有意义。

我检查了递归包含,我发现头文件(递归地)包含一些
\include“windows.h”
\include“Winsock.h”
并编写了一个
\include“Winsock2.h”
。在这个文件中,我添加了
#include“Winsock2.h”
作为第一个include

耐心一点,逐个查看包含并建立此顺序,首先
#包含“Winsock2.h”
,然后
#包含“windows.h”

在我的项目中(我使用VS 2008 SP1)工作下一个解决方案:

头文件:

//myclass.h
#pragma once
#define _WINSOCKAPI_
#include <windows.h>
其中#include“winsock2class.h”表示实现winsock2.h的类:

//winsock2class.h
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "Ws2_32.lib")
//winsock2class.h
#包括
#包括
#pragma注释(lib,“Ws2_32.lib”)

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

#define _WINSOCKAPI_
但以下情况不会:

#define WIN32_LEAN_AND_MEAN

实际上,我遇到了一个问题,我必须将winsock2.h定义为第一个包含,似乎它与其他包中的包含有其他问题。希望这对遇到相同问题的人有所帮助,不仅仅是windows.h,还有all includes。

您已经使用了一次#pragma,所以应该只包含一次。您的编译器不会
//myclass.h
#pragma once
#define _WINSOCKAPI_
#include <windows.h>
//myclass.cpp
#include "Util.h"
#include "winsock2class.h"
#pragma comment(lib, "Ws2_32.lib")
//winsock2class.h
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "Ws2_32.lib")
#define _WINSOCKAPI_
#define WIN32_LEAN_AND_MEAN