文件重定义冲突的分析与解决

突兀森郁0

突兀森郁0

2016-01-29 12:26

文件重定义冲突的分析与解决,文件重定义冲突的分析与解决

文件重定义冲突的分析与解决

作者:hrg21

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/)


引言


  有时候看到论坛上有人问编译时重定义现象的问题。这个问题与头文件包含冲突有关,改一改相关头文件包含就会让问题消失。我在这里要以 <windows.h <winsock.h <winsock2.h这3个头文件为例分析为什么会产生这种原因;然后给出一种不会产生冲突的做法;最后就此例的分析给出结论。本文对于已经知道冲突原因的读者是多余的,但对于一时没有时间去解的人还是有一定的参考价值的。


一个重命名的例子

先写一个socket基本操作类:

// SocketBase.h#ifndef _SOCKET_BASE_H_#define _SOCKET_BASE_H_#include <winsock2.h#pragma comment(lib, "ws32_2.lib")class Socket{};#endif
写一个TCP监听类,它从Socket派生:
// TcpListener.h    #ifndef _TCP_LISTENER_H_#define _TCP_LISTENER_H_#include "SocketBase.h"class TcpListener : Socket{};#endif
在基于MFC的工程中用 TcpListener 监听客户连接,同时这个地方须要用到 Windows 某些头文件。
#include "stdafx.h"    #include "TcpListener.h"void fun(){    TcpListener* listen = new TcpListener;    ……}
下面是头文件包含关系:
Stdafx.h - windows.h - winsock.h  winsock2.hTcpListener.h - SocketBase.h - winsock2.h
  编译,出现N多重定义错误。这个错误与stdafx.h中的 windows.h 和TcpListener.h 的winsock2.h 有关,下面说两种消除错误的方法。


针对本工程中消除编译

错误产生的原因是 windows.h 中有:
    #include <winsock.h    #include <winsock2.h
  产生重定义的是 windows.h 中的 winsock.h 相关定义与 TcpListener.h 中 winsock2.h 相关定义冲突。相同头文件是不会冲突的,因为有 "#ifndef #define …. #endif";如果windows中只包含一个winsock2.h就不会产生重定义了。
  现在我们只要把 SocketBase.h 中的 "include <winsock2.h 和 #pragma…"注释了就编译通过了。但经过注释的 SocketBase.cpp 与 TcpListener.cpp 单独编译就通不过了。这种只是针对特定的环境下解决问题,我们得想一个比较专业的办法。


一个可被接受的解决方法

  Winsock2.h 与 windows.h 中的 winsock.h 相关项的重定义要在 SocketBase.h 中避免。在 SocketBase.h加一些编译条件就可以做到这一点,经过修改的 SockBase.h 如下:
#ifndef _SOCKET_BASE_H_#define _SOCKET_BASE_H_#ifndef _WINSOCKAPI_           // 没有包含winsock.h#define _WINSOCKAPI_           // 避免再包含winsock.h    #ifndef _WINSOCK2API_      // 没有包含winsock2.h    #define _WINSOCK2API_      // 避免再包含winsock2.h        #include <winsock2.h        #pragma comment(lib, "ws32_2.lib")    #endif#endifclass Socket{};#endif
经过这样修改,就能做到 winsock.h 与 winsock2.h 中的相关项重定义了。


结论

  通过对上述例子的分析解决,同样在其它类似的问题中适用。如果有更简单的方法避免重定义的情况出现,请告诉我一下。


参考Win32 sdk中的 windows.h;Win32 sdk中的 winsock.h;Win32 sdk中的 winsock2.h;
展开更多 50%)
分享

猜你喜欢

文件重定义冲突的分析与解决

C语言教程 C语言函数
文件重定义冲突的分析与解决

setAttribute 与 class冲突解决

Web开发
setAttribute 与 class冲突解决

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

重定义编译DLL文件的基地址

编程语言 网络编程
重定义编译DLL文件的基地址

xheditor与validate插件冲突的解决方案

Web开发
xheditor与validate插件冲突的解决方案

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

java 重定义数组的实现方法(与VB的ReDim相像)

编程语言 网络编程
java 重定义数组的实现方法(与VB的ReDim相像)

让诺顿防火墙与文件共享不再冲突

电脑网络
让诺顿防火墙与文件共享不再冲突

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

指向类成员

指向类成员

Flash新手入门教程:AS代码实现鼠标拖拽效果_母鸡下蛋

Flash新手入门教程:AS代码实现鼠标拖拽效果_母鸡下蛋
下拉加载更多内容 ↓