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 );
   }

};

      

+1


source to share


3 answers


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);
    }
};

      

+5


source


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);

      

+2


source


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.

0


source







All Articles