How to use System :: Threading :: Interlocked :: Increment on a static variable from C ++ / CLI?
I would like to keep a static counter in a garbage-collected class and increment it with Interlocked :: Increment. What is the C ++ / CLI syntax for this?
I've tried options for the following but no luck so far:
ref class Foo
{
static __int64 _counter;
__int64 Next()
{
return System::Threading::Interlocked::Increment( &_counter );
}
};
source to share
You need to use tracking link in value _int64
using% tracking link reference:
ref class Bar
{
static __int64 _counter;
__int64 Next()
{
__int64 %trackRefCounter = _counter;
return System::Threading::Interlocked::Increment(trackRefCounter);
}
};
source to share
Just remove the operator-address:
return System::Threading::Interlocked::Increment( _counter );
In C ++ / CLI, for example C ++, there is no special notation for passing by reference.
or you can use the built-in function, InterlockedIncrement64
( #include <windows.h>
)
return ::InterlockedIncrement64(&_counter);
source to share
The suggestion to use native functions / macros (i.e. InterlockedExchangePointer
, etc. plus a lot of cool ones that I did not know about, such as InterlockedXor64
) is very difficult thereby that it can lead to the fact that the internal (at least with settings compiler by default) will be removed into your managed function C++/CLI
. When this happens, your entire function will be compiled as native.
And managed versions Interlocked::*
are good too, because you don't need pin_ptr
if the target is in a GC object. However, as noted on this page, it can be a real pain to find the right spells to make it work, especially if you want to swap places (like the pointers themselves). Here's how:
int i1 = 1, i2 = 2;
int *pi1 = &i1, *pi2 = &i2, *pi3;
pi3 = (int*)Interlocked::Exchange((IntPtr%)pi1, IntPtr(pi2)).ToPointer();
I have confirmed that this works correctly, despite the suspiciously frustrating lack of addressing ( &
) on a pointer pi1
. But it makes sense when you think about it, because if the target is moving in the GC host, you don't want to do the usual thing **
by grabbing the &
(own) address of the pointer itself.
source to share