英特尔 TBB - "初始化关键部分 Ex":找不到标识符编译器错误
Intel TBB - 'InitializeCriticalSectionEx': identifier not found compiler error
我有一个依赖OpenCV和TBB的VS(C (项目,因此我为每个库创建了属性表,并将其包括在项目中。一切都很好,并且编译了代码。
昨天,我已经开始使用VCPKG软件包管理器。我通过VCPKG安装了OpenCV和TBB,一切似乎都起作用。我创建了一个空的项目,其中包括两者的标题,并测试了新编译的库是否有效。验证这一点后,我回到了主要项目并删除了属性表,因此我可以使用VCPKG的库。自上次成功编译以来,我没有以任何方式更改代码。
但是,当我尝试编译代码时,我两次都会收到此错误(在main.cpp和subpoule中(
tbb critical_section.h(53(:错误c3861:'prinitizecriticalsectionex':找不到标识符
有人知道这里发生了什么还是为什么发生此错误?
更新
我自己发现了错误。我正在添加Poco-libraries标签,因为它实际上是TBB和Poco之间的冲突。
我找到了问题的根源,实际上它与TBB无关,而与POCO库无关。
考虑最小示例:
#include <Poco/Poco.h>
#include <tbb/tbb.h>
void main()
{
}
这将抛出编译器错误。
追踪路径
包括 tbb.h , criality_section.h 包括 tbb.h 的第51行中。但是, ciritcal_section.hpp 包括 Machine/winwdows_api.h 看起来像这样(切掉不必要的东西(:
tbb/Machine/winwdows_api.h:
#if _WIN32 || _WIN64
#include <windows.h>
#if _WIN32_WINNT < 0x0600
#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx
inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD )
{
return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount );
}
#endif
您可以看到, windows.h 在检查 _WIN32_WINNT
宏之前包括。此宏定义在 sdkddkver.h (其中包含在 windows.h 中(,如果尚未定义(在我的情况下,它将设置为win10(:
sdkddkver.h:
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0A00
#endif
在 Windows.h 中,_WIN32_WINNT
宏控制实际上包括Windows头文件的哪个版本。如果将_WIN32_WINNT
设置为更早的版本,而不是Windows Vista,则未定义函数InitializeCriticalSectionEx
。
通过简单地定义称为适当的替代功能的宏InitializeCriticalSectionEx
,通过 Machine/winwdows_api.h (如您在该文件的代码块中看到的那样(捕获。
到目前为止很好。
问题
所有邪恶的根源在于poco库的 poco/untindows.h 。包括POCO标头时,将包括某个点 undindows.h 。
poco/untindows.h (缩短(:
#if defined(_WIN32_WINNT)
#if (_WIN32_WINNT < 0x0501)
#error Unsupported Windows version.
#endif
#elif defined(NTDDI_VERSION)
#if (NTDDI_VERSION < 0x05010100)
#error Unsupported Windows version.
#endif
#elif !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#define NTDDI_VERSION 0x05010100
#endif
#endif
#include <windows.h>
预处理器检查,如果_WIN32_WINNT
已经定义,如果没有定义,则将其设置为Windows XP的0x0501。之后,包括 Windows.h 。在上一章中,我提到_WIN32_WINNT
实际上包含了哪个版本的Windows头文件。
现在想象,我们项目中的第一个包括Poco的标题。这意味着,_WIN32_WINNT
将设置为Windows XP和 Windows.h 将包括 Windows XP 的Windows标题(IMO已经是一个不好的符号(。
但不用担心,情况会变得更糟。
如果我们跟踪Include层次结构一个级别,我们可以联系 poco/platform_win32.h 。
poco/platform_win32.h (缩短(:
#include "Poco/UnWindows.h"
...
#if defined (_WIN32_WINNT_WINBLUE)
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
...
有趣,不是吗?首先,它包括 unvindows.h ,它设置了_WIN32_WINNT
并导致Windows XP标头,接下来它重新定义_WIN32_WINNT
为Windows 8.1。我不知道为什么这样做,也许有充分的理由,idk。
现在,如果我们现在查看最顶部的最小示例,我们会看到POCO在TBB之前包括。现在发生的事情是:
- 包括Poco标头
- 将
_WIN32_WINNT
设置为Windows XP - 包括Windows标题(由于2(,Windows XP版本
- 重置
_WIN32_WINNT
到Windows 8.1 - 包括TBB标头(已经包含Windows标题,因此TBB不需要再次将它们包含在 tbb/windows_api.h (
- TBB通过
_WIN32_WINNT
检查Windows版本,并识别Windows 8.1(由POCO设置( - TBB认为
InitializeCriticalSectionEx
是定义的,因为Windows版本为8.1(或者是?Poco说:获取REKT(,并且InitializeCriticalSectionEx
是因为Windows Vista。 - 不幸的是,Poco确保了Windows XP标头已加载,因此编译器说:否。
解决方案
包括 windows.h 自己事先设置_WIN32_WINNT
自己设置为
#define _WIN32_WINNT 0x0A00 // either this
#include <Windows.h> // or this
#include <Poco/Poco.h>
#include <tbb/tbb.h>
void main()
{
}
也许Poco贡献者的某人可以在这里澄清一些事情。POCO版本是用X64构建的1.8.1-1(通过VCPKG(。
更新
Poco在这个问题上。更新可以在此处找到。
- 设置 Visual Studio for MPI: 找不到标识符错误
- 找不到标识符合并
- 从子类访问模板类成员时出现"找不到标识符"错误
- OpenCV 3 错误"CV_FOURCC":找不到标识符
- im调用函数时找不到标识符?
- clock_gettime:在 Windows 10 的 Visual Studio 中找不到标识符
- 英特尔 TBB - "初始化关键部分 Ex":找不到标识符编译器错误
- 找不到标识符.C3861
- 在void tryagain()上找不到标识符
- 在C 类中找不到标识符
- 找不到标识符,尝试在 C++ 中显示数组值
- 我遇到:错误2错误C3861:"fx":找不到标识符
- OpenGL - 'glTexSubImage3D':找不到标识符
- "GetProcessIdOfThread":找不到标识符
- 错误 C3861:"strcpy_y":找不到标识符
- "printf":找不到标识符
- 错误 C3861:"initNode":找不到标识符
- 在抽象类中找不到C++标识符
- 错误 C3861:"getGaborKernel":找不到标识符
- 错误 C3861:"对齐":找不到标识符