ATL 宏 END_CONNECTION_POINT_MAP 中的警告 C4640

Posted

技术标签:

【中文标题】ATL 宏 END_CONNECTION_POINT_MAP 中的警告 C4640【英文标题】:Warning C4640 in ATL Macro END_CONNECTION_POINT_MAP 【发布时间】:2016-07-25 03:57:15 【问题描述】:

我收到警告

warning C4640: '_entries': construction of local static object is not thread-safe

来自 ATL 宏 END_CONNECTION_POINT_MAP,例如

BEGIN_CONNECTION_POINT_MAP(CMBusInclinometerTemChannel)
  CONNECTION_POINT_ENTRY(__uuidof(IChannelEvents))
END_CONNECTION_POINT_MAP()

在 C++ ATL/COM 项目中。

我认为这在安装 Visual Studio 2015 更新 2 后就开始发生了。

有人能解决这个问题吗?

【问题讨论】:

【参考方案1】:

我认为这可能是一个新警告,但不是 - it was earlier just turned off by default。我想这是一个长期存在的“问题”,但是将其转换为真正的错误可能并不容易(如果可能并且有副作用)。

问题在于内部使用静态局部变量_entries 的连接点映射,该变量在首次使用时以线程不安全的方式初始化。然而,它是指针所指的具有固定值的指针的初始化。问题可能是线程#1 将映射视为已初始化,而线程#2 只是在初始化的中间。非常罕见的情况,难怪到目前为止没有投诉。

解决办法可能是用全局临界区锁包围静态变量初始化,比如

ATLASSERT(_pAtlModule);
CComCritSecLock<CComCriticalSection> Lock(_pAtlModule->m_csStaticDataInitAndTypeInfo);
static ...

在地图宏中,并使用#pragma 抑制警告。这应该是 ATL 标头代码 (atlcom.h) 中的修复。

【讨论】:

感谢@roman-r,我已在 stdafx.h 中使用 #pragma 警告(禁用:4640)禁用它。由于某种原因,它只适用于直接包含在 stdafx.h 中的头文件,但这是另一个问题。 connect.microsoft.com/VisualStudio/feedback/details/2539759/…

以上是关于ATL 宏 END_CONNECTION_POINT_MAP 中的警告 C4640的主要内容,如果未能解决你的问题,请参考以下文章

USES_CONVERSION宏(转)

ATL中宏定义offsetofclass的分析

COM聚合

厦门atl在哪里

将实现 ATL 接口的 VBA 类传递给 ATL 方法

错误 C2664:无法将参数 2 从 'const ATL::CAdapt<ATL::CComPtr<IZipFileEntry>> *' 转换为 'ATL::CAdapt&l