我想在垃圾收集类中保留一个静态计数器并使用 Interlocked::Increment 递增它。执行此操作的 C++/CLI 语法是什么?
我一直在尝试以下变化,但到目前为止没有运气:
ref class Foo
{
static __int64 _counter;
__int64 Next()
{
return System::Threading::Interlocked::Increment( &_counter );
}
};
我想在垃圾收集类中保留一个静态计数器并使用 Interlocked::Increment 递增它。执行此操作的 C++/CLI 语法是什么?
我一直在尝试以下变化,但到目前为止没有运气:
ref class Foo
{
static __int64 _counter;
__int64 Next()
{
return System::Threading::Interlocked::Increment( &_counter );
}
};
您需要使用% tracking reference 表示法对您的_int64
值使用跟踪引用:
ref class Bar
{
static __int64 _counter;
__int64 Next()
{
__int64 %trackRefCounter = _counter;
return System::Threading::Interlocked::Increment(trackRefCounter);
}
};
只需删除地址操作符:
return System::Threading::Interlocked::Increment( _counter );
在 C++/CLI 中,与 C++ 一样,没有用于通过引用传递的特殊符号。
或者您可以使用本机函数InterlockedIncrement64
( #include <windows.h>
)
return ::InterlockedIncrement64(&_counter);
使用本机函数/宏(即InterlockedExchangePointer
,等等......加上很多我不知道的很酷的,例如InterlockedXor64
)的建议受到严重阻碍,因为这样做会导致内在(至少在默认编译器设置)被放入您的托管C++/CLI
函数中。发生这种情况时,您的整个函数将被编译为本机。
并且托管版本也很好,因为如果目标位于 GC 对象中,则Interlocked::*
不必这样做。pin_ptr
但是,正如本页所述,找到正确的咒语以使其正常工作可能会非常痛苦,尤其是当您想要交换(即)本机指针本身时。就是这样:
int i1 = 1, i2 = 2;
int *pi1 = &i1, *pi2 = &i2, *pi3;
pi3 = (int*)Interlocked::Exchange((IntPtr%)pi1, IntPtr(pi2)).ToPointer();
我验证了这确实可以正常工作,尽管指针上缺少地址获取 ( &
)令人怀疑地令人不安。pi1
但这是有道理的,当您考虑它时,因为如果目标在 GC 主机中移动,您不会希望**
通过抓取&
指针本身的(本机)地址来做通常的事情。