【问题标题】:Cannot include both files (WinSock2, Windows.h)不能同时包含这两个文件(WinSock2、Windows.h)
【发布时间】:2014-02-19 09:37:03
【问题描述】:

我在包含这两个文件时遇到了问题。 现在,我知道我需要先包含 Winsock2,然后再包含 windows.h,或者简单地说:

#define WIN32_LEAN_AND_MEAN

但是,我还是有问题

我有一个名为 XS.h 的头文件,看起来像这样

#ifndef XS_H
#define XS_H

#include <winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>

#endif

我将XS.h 包含在标题Client.h 中。 Client.h include 看起来像这样:

#ifndef CLIENT_H
#define CLIENT_H

#include "XS.h"

XS.h 是我唯一包含在 Client.h 中的,但我仍然遇到错误(如您所见,Winsock 包含在 windows.h 之前

我收到了大约 78 个错误,以下是其中的一些:

Error   90  error C3861: 'WSASetLastError': identifier not found    c:\program files (x86)\windows kits\8.0\include\um\ws2tcpip.h   703
Error   61  error C2375: 'WSAStartup' : redefinition; different linkage c:\program files (x86)\windows kits\8.0\include\um\winsock2.h   2296
Error   49  error C2375: 'send' : redefinition; different linkage   c:\program files (x86)\windows kits\8.0\include\um\winsock2.h   2026

我该如何解决这个问题?

谢谢!

编辑:我也尝试过使用#define _WINSOCKAPI_,尽管它没有解决我的问题...... 我先有winsock.h,然后是windows.h,尽管它仍然对我有错误。

【问题讨论】:

  • 在头文件中使用#pragma once
  • 我建议总是首先在每个源文件中包含 windows.h 和 windowsx.h(最好使用 stdafx.h 文件)。我不确定它是否能解决这个特殊问题,但它可以大大减少混乱。
  • 我已将Client.h 更改为:#pragma once #include &lt;winsock2.h&gt; #include &lt;ws2tcpip.h&gt; #include "Chat.h" 虽然它仍然不起作用,同样的错误......
  • 微软的“智能感知”不使用与编译器相同的分析引擎,因此它可以并且确实为完全有效的代码吐出“错误消息”。也就是说,这听起来是一个真正的问题,而不仅仅是一个 Intellisense 明显的问题。在包含任何其他 Windows API 标头之前,您应该始终包含 windows.h。这是因为 Microsoft 标头通常不包含他们需要的所有内容,即不遵循良好的编程习惯。可以只将&lt;windows.&gt; 强制包含,但这会重复导致问题的弊端:更好地修复源代码。

标签: c sockets winapi winsock2


【解决方案1】:

将包含添加到 pch.h:

// TODO: add headers that you want to pre-compile here
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

【讨论】:

    【解决方案2】:

    我确保#include "Winsock2.h" 在任何#include "windows.h""#include "Winsock.h" 之前,这解决了这个问题。

    只是耐心的问题,看包括一个一个并建立这个顺序,先#include "Winsock2.h"然后#include "windows.h"

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

    【讨论】:

    • 我意识到这是一篇旧帖子,但上述解决方案并不总是有效。有 3rd 方库可以并且将包含您不知道的 windows.h。一个让我印象深刻的好例子:Qt 的头文件 QSGGeometry。我的偏好是为不需要 winsock 的任何 (CMake) 模块定义 WIN32_LEAN_AND_MEAN。
    【解决方案3】:

    确保&lt;windows.h&gt; 不包含&lt;winsock.h&gt;(它提供许多与&lt;winsock2.h&gt; 相同的声明)。在我系统上的&lt;winsock2.h&gt; 文件中有这一行:

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

    _WINSOCKAPI_ 包含守卫可能是一个内部实现细节,但作为一个实用的解决方案,我会依赖它,只需在包含 &lt;windows.h&gt; 之前定义此符号,例如在编译器调用中(对于 IDE 意味着在 IDE 项目设置中)。

    或者,您可以尝试always include &lt;winsock2.h&gt; before &lt;windows.h&gt;,以建立相关的包含防护(但我认为这比假设上述防护实际上定义明确要脆弱得多);

    或者您可以定义WIN32_LEAN_AND_MEAN,它可以防止&lt;windows.h&gt; 包含&lt;winsock.h&gt; 以及其他一些标头(从我系统上的源代码中列出&lt;cderr.h&gt;&lt;dde.h&gt;&lt;ddeml.h&gt;&lt;dlgs.h&gt; ,&lt;lzexpand.h&gt;,&lt;mmsystem.h&gt;,&lt;nb30.h&gt;,&lt;rpc.h&gt;,&lt;shellapi.h&gt;,&lt;winperf.h&gt;,&lt;wincrypt.h&gt;,&lt;winefs.h&gt;,&lt;winscard.h&gt;,&lt;mmsystem.h&gt;,&lt;mmsystem.h&gt;,&lt;ole2.h&gt;,) .我不建议依赖WIN32_LEAN_AND_MEAN 优化正确性

    即最小值:

    #undef UNICODE
    #define UNICODE
    #undef _WINSOCKAPI_
    #define _WINSOCKAPI_
    #include <windows.h>
    #include <winsock2.h>
    
    auto main()
        -> int
    {}
    

    【讨论】:

    • 原来,我在我的主源文件中包含 windows.h,这导致了问题,然后 WINSOCKAPI 修复了其他错误...谢谢!
    • WIN32_LEAN_AND_MEAN不是最佳选择吗?为什么它不起作用?使用时的包含顺序是什么?
    • 显然没有明确的“最佳”选择。例如,考虑使用依赖于&lt;windows.h&gt; 的第三方标头,拖入一个或多个被WIN32_LEAN_AND_MEAN 排除的标头。 original documentation 只是将效果定义为“参考 Windows.H 以确定将被排除的文件”。因此,这两种方法都基于查找 MS 标头代码,该代码可能会发生变化。当排除列出的标题没有问题时,也许可以同时使用。
    猜你喜欢
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多