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