将 Winsock2 添加到我的 MinGW-w64 C/C++ 会导致:未定义对“InitializeConditionVariable”的引用

Posted

技术标签:

【中文标题】将 Winsock2 添加到我的 MinGW-w64 C/C++ 会导致:未定义对“InitializeConditionVariable”的引用【英文标题】:Adding Winsock2 to my MinGW-w64 C/C++ causes: undefined reference to `InitializeConditionVariable' 【发布时间】:2021-05-06 18:44:04 【问题描述】:

当我将 winsock2 添加到我的 MinGW-w64 C/C++ 项目时,它会出现 make 错误: 对“InitializeConditionVariable”的未定义引用。

注意:在添加 Winsock 之前,InitializeConditionVariable 已构建并运行正常。

main.c ...

    #undef UNICODE
    
    #define WIN32_LEAN_AND_MEAN
    
    
    #include <winsock2.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <errno.h>
    #include <string.h>
    #include <unistd.h>
    #include <signal.h>
    
    #include "infrastructure.h"
    #include "common.h"
    #include "bg.h"
    #include "aox.h"
    
    #include <windows.h>
    #include <ws2tcpip.h>
    
    #include <synchapi.h>

. . . 

static void mutexInit()

#ifdef WINDOWS
  // Initialize critical sections and condition variables
  InitializeCriticalSection(&iqSamplesCriticalSection);
  InitializeCriticalSection(&bgBufferCriticalSection);
  InitializeConditionVariable(&newSamplesAvailable);   <<<<<<<<<<<<<<<<<<< ERROR: undefined reference
#else
  // Initialize mutexes
  pthread_mutex_init(&iqSamplesCriticalSection, NULL);
  pthread_mutex_init(&bgBufferCriticalSection, NULL);
  pthread_cond_init(&newSamplesAvailable,NULL);
#endif

【问题讨论】:

您是否有理由不使用std 互斥体和条件变量?另外,我认为某些版本的 MinGW(至少是 MSYS2 版本)包括 Windows 端口的 pthread。 HBC: ...因为我“继承”了代码。是的,一种解决方案是用 std 替换互斥锁。 "注意:InitializeConditionVariable 在添加 Winsock 之前构建并运行正常" - 我认为这不太可能。 WinSock API 不会影响编译器+链接器处理InitializeConditionVariable() 的方式。其他事情正在发生。 【参考方案1】:

InitializeConditionVariable() 与 WinSock 无关。这完全是您自己的代码的问题。

InitializeConditionVariable() 是在 Windows Vista 中引入的。您可能只是链接到过时的kernel32.lib,它不会公开较新的 Vista+ API。因此,您可以:

为您的编译器更新 Windows SDK。

在运行时使用GetProcAddress()动态加载各种ConditionVariable functions。

【讨论】:

MSYS2 GCC 编译 InitializeConditionVariable 开箱即用,没有任何额外的标志。不确定如何在 MinGW 上更新 Windows SDK,因此切换到 MSYS2 可能会更容易。 编译和链接是两个不同的步骤。您收到的是链接器错误,而不是编译器错误。您的 MinGW 的kernel32.lib 副本可能没有从kernel32.dll 导入InitializeConditionVariable() 的条目,就像InitializeCriticalSection()(这是一个更旧的API)一样。您可以检查 MinGW 是否有任何工具可以从 kernel32.dll 本身重新生成其 kernel32.lib 用错词了,对不起。应该说“开箱即用”。它编译、链接和运行没有任何错误。 注意:InitializeConditionVariable 在添加 Winsock 之前构建并运行正常。 这完全没有意义。请参阅我的其他评论。

以上是关于将 Winsock2 添加到我的 MinGW-w64 C/C++ 会导致:未定义对“InitializeConditionVariable”的引用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 javascripts 添加到我的 InDesign Server Java Web 应用程序?

使用 mingw-w64 编译 mex 的链接器错误

如何在Rails 3应用程序中将gem添加到我的vendor / cache目录?

尝试将片段添加到我的片段容器 FrameLayout

尝试将片段添加到我的片段容器 FrameLayout

将 ScrollView 添加到我的 XML 布局文件后应用程序崩溃