带有托管 C++ 的 InterlockedIncrement64

InterlockedIncrement64 with managed C++

我正在移植在 Visual Studio 2012 下编写的代码,以便用 Visual Studio 2015 编译。代码可以在 Windows 2012 上构建。

我遇到一些调用 InterlockedIncrement64 的代码的问题。它为 x64 目标构建正常,但在目标为 Win32 且调用代码被管理(即使用 /clr 编译)的情况下失败,产生:

error C3861: 'InterlockedIncrement64': identifier not found

查看winnt.h,目标为Win32 时InterlockedIncrement64 似乎未定义,而_MANAGED 已定义。

我可以重新安排代码,这样托管代码就不会调用 InterlockedIncrement64,但我仍然很想知道为什么 Visual Studio 2015 会出现这种行为变化。

顾名思义,InterlockedIncrement64是一个LONGLONG的原子自增操作,需要内存64位对齐.

鉴于您不能在托管代码中设置内存对齐并且它可能用于托管class成员,那么这个限制是有意义的(对我来说): "...否则,此函数在多处理器 x86 系统和任何非 x86 系统上的行为将不可预测。"。想想这个:

::InterlockedIncrement64(&_memberVariable);

如果 _memberVariable 分配在 managed world 中,那么它不会是 64 位对齐的(尽管它可能偶然发生),并且 此代码对于 Win32 总是会失败。定义_MANAGED去掉这个函数更简单

解决方法:检查 #ifdef _MANAGED 并改为调用 Interlocked::Increment,或者放弃原子性 (!) 但在递增后包含内存屏障。