windows.h和winsock2.h解决办法

1 首先明确一个概念 # ifndef

                   #define

                   #endif

举例说明

animal.h

#ifndef ANIMAL_H_H      //我们一般用#define定义一个宏,是为了在程序中使用,使程

                            序更加简洁,维护更加方便,然而在此处,我们只是为了判断

#define ANIMAL_H_H      ANIMAL_H_H是否定义,以此来避免类重复定义,因此我们没有为

                        其定义某个具体的值。在选择宏名时,要选用一些不常用的名字,

class animal            因为我们的程序经常会跟别人写的程序集成,如果选用一个很常用

                        的名字(例如:X),有可能会造成一些不必要的错误

{

public:

     animal();

     ~animal();

     void eat();

     void sleep();

     virtual void breathe();

};

#endif

 

fish.h

#include "animal.h"

#ifndef FISH_H_H

#define FISH_H_H

class fish:public animal

{

public:

     void breathe();

};

#endif

我们再看EX10.cpp的编译过程。当编译器展开animal.h头文件时,条件预处理指令判断ANIMAL_H_H没有定义,于是就定义它,然后继续执行,定义了animal这个类;接着展开fish.h头文件,而在fish.h头文件中也包含了animal.h,再次展开animal.h,这个时候条件预处理指令发现ANIMAL_H_H已经定义,于是跳转到#endif,执行结束。

通过分析,我们发现在这次的编译过程中,animal这个类只定义了一次。

明白了这个概念 在分析。

Windows网络编程至少需要两个头文件:winsock2.hwindows.h

先来分析 winsock.h

#ifndef _WINSOCK2API_

#define _WINSOCK2API_

#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */

_WINSOCK2API_很容易理解,这是最常见的防止头文件重复包含的保护措施。_WINSOCKAPI_的定义则是为了阻止对winsock.h的包含

/*

 * Ensure structures are packed consistently.

 */

 

#include <pshpack4.h>

 

/*

 * Default: include function prototypes, don't include function typedefs.

 */

 

#ifndef INCL_WINSOCK_API_PROTOTYPES

#define INCL_WINSOCK_API_PROTOTYPES 1

#endif

 

#ifndef INCL_WINSOCK_API_TYPEDEFS

#define INCL_WINSOCK_API_TYPEDEFS 0

#endif

 

/*

 * Pull in WINDOWS.H if necessary

 */

#ifndef _INC_WINDOWS

#include <windows.h>

#endif /* _INC_WINDOWS */

这里有两个关键点:

(1)      winsock.h内部当_INC_WINDOWS 没有被定义时 会自动调用windows.h

在这里我们在分析一下 windows.h

1)      windows.h内部也定义了

  _INC_WINDOWS winsock2.h

如下:

#ifndef _INC_WINDOWS(基本上在windows.h开始位置)

#define _INC_WINDOWS

。。。。。。(省略)

#ifndef WIN32_LEAN_AND_MEAN

#include <cderr.h>

#include <dde.h>

#include <ddeml.h>

#include <dlgs.h>

#ifndef _MAC

#include <lzexpand.h>

#include <mmsystem.h>

#include <nb30.h>

#include <rpc.h>

#endif

#include <shellapi.h>

#ifndef _MAC

#include <winperf.h>

 

#if(_WIN32_WINNT >= 0x0400)

#include <winsock2.h>

#include <mswsock.h>

#else

#include <winsock.h>

#endif /* _WIN32_WINNT >=  0x0400 */

 

#endif

#ifndef NOCRYPT

#include <wincrypt.h>

#endif

 

#ifndef NOGDI

#include <commdlg.h>

#ifndef _MAC

#include <winspool.h>

#ifdef INC_OLE1

#include <ole.h>

#else

#include <ole2.h>

#endif /* !INC_OLE1 */

#endif /* !MAC */

#endif /* !NOGDI */

#endif /* WIN32_LEAN_AND_MEAN */

#endif /* _INC_WINDOWS */windows.h倒数第二句)

#endif /* _WINDOWS_ */ windows.h最后一句)

如果WIN32_LEAN_AND_MEAN没有定义同时WIN32_WINNT >= 0x0400 就会调用

#include <winsock2.h>

#include <mswsock.h>两句

而以‘SOCKET’为例mswsock.h(69) : error C2065: 'SOCKET' : undeclared identifier

原因就在于 mswsock.h 只是用到了‘SOCKET’而SOCKET是在winsock2.h中被定义的 而且SOCKET的位置在

#ifndef _INC_WINDOWS

#include <windows.h>

#endif /* _INC_WINDOWS */

………………..

typedef u_int           SOCKET;

请读者认真看#ifndef _INC_WINDOWS

#include <windows.h>

#endif /* _INC_WINDOWS */

 typedef u_int           SOCKET; winsock2.h的相对位置SOCKET#ifndef _INC_WINDOWS

#include <windows.h>

#endif /* _INC_WINDOWS */

其后被定义 所以

在如果先包含winsock2.h再包含windows.h,如果WIN32_LEAN_AND_MEAN未定义且_WIN32_WINNT大于或等于0x400,那么会在winsock2.h—windows.h----mswsock.h,此时,mswsock.h里所用的SOCKET类型还尚未定义,因此会出现类型未定义错误.

第二种错误

winsock2.h(99) : error C2011: 'fd_set' : 'struct' type redefinition

错误情形2

先包含windows.h再包含winsock2.h,如果WIN32_LEAN_AND_MEAN未定义且_WIN32_WINNT未定义或者其版本号小于0x400,那么windows.h会自动导入winsock.h,这样再当winsock2.h被包含时便会引起重定义。

清楚了吧。

  

      再附上一个示例:

#include <windows.h>

#include <winsock2.h>

#pragma comment(lib,"jrtplib.lib")

#pragma comment(lib,"jthread.lib")

#pragma comment(lib,"ws2_32.lib")

#include "header/rtpsession.h"
#include "header/rtppacket.h"
#include "header/rtpudpv4transmitter.h"
#include "header/rtpipv4address.h"
#include "header/rtpsessionparams.h"
#include "header/rtperrors.h"

在程序中 我设计了一个RTP传输类(General Class) 而且在类中没有使用头文件(stdafx.h)

一开始我把

#include <windows.h>

#include <winsock2.h> 放在 #include "header/rtperrors.h" 后面一编译出现了 102 个error(就是上面提到的错误一)

后来我一想很奇怪,没可能性呀。然后我发现了 Jrtplib 的这一堆头文件 我想有一种可能性 就是 在诸如rtpudpv4transmitter.h

中可能也引入了winsock2.h 所以又造成了 错误1 的出现。晚上有时间验证一下。

你可能感兴趣的:(windows,socket,api,function,Class,include)