我正在移植在Visual Studio 2012下编写的代码以与Visual Studio 2015一起编译。该代码在Windows 2012上可以正常运行。
我有一些调用InterlockedIncrement64
的代码有问题。它为x64目标建立了OK,但在目标是Win32并且管理调用代码(即用/clr
编译)的情况下失败了,结果是:
错误C3861:“ InterlockedIncrement64”:找不到标识符
在winnt.h中,当目标是Win32且定义了InterlockedIncrement64
时,似乎_MANAGED
是未定义的。
我可以重新排列代码,以便不为托管代码调用InterlockedIncrement64
,但是我仍然很好奇为什么Visual Studio 2015会带来这种行为变化。
最佳答案
顾名思义,InterlockedIncrement64
是LONGLONG
的原子增量操作,它需要64位对齐的内存。
鉴于您无法在托管代码中设置内存对齐方式,并且可以将其用于托管类成员,那么此限制对我来说很有意义:“ ...否则,此功能在多处理器x86系统和任何非x86系统。”。考虑一下:
::InterlockedIncrement64(&_memberVariable);
如果
_memberVariable
是在托管环境中分配的,则它不会是64位对齐的(尽管可能偶然发生),并且此代码对于Win32总是会失败。定义_MANAGED
时删除此函数更简单。解决方法:检查
#ifdef _MANAGED
并改为调用Interlocked::Increment
,或者降低原子性(!),但在递增之后包括一个内存屏障。