Comment utiliser System :: Threading :: Interlocked :: Increment sur une variable statique à partir de C ++ / CLI?

StackOverflow https://stackoverflow.com/questions/342140

  •  19-08-2019
  •  | 
  •  

Question

Je voudrais conserver un compteur statique dans une classe ordonnée et l'incrémenter à l'aide d'Interlocked :: Increment. Quelle est la syntaxe C ++ / CLI pour ce faire?

J'ai essayé des variantes, mais je n’ai pas eu de chance:

ref class Foo
{
   static __int64 _counter;

   __int64 Next()
   {
      return System::Threading::Interlocked::Increment( &_counter );
   }

};
Était-ce utile?

La solution

Vous devez utiliser une référence de suivi . à votre _int64 valeur, en utilisant la notation% tracking reference:

ref class Bar
{
    static __int64 _counter;

    __int64 Next()
    {
        __int64 %trackRefCounter = _counter;
        return System::Threading::Interlocked::Increment(trackRefCounter);
    }
};

Autres conseils

Supprimez simplement l'adresse de l'opérateur:

return System::Threading::Interlocked::Increment( _counter );

En C ++ / CLI, comme le C ++, il n’existe pas de notation spéciale permettant de passer par référence.

ou vous pouvez utiliser la fonction native, InterlockedIncrement64 (#include <windows.h>)

return ::InterlockedIncrement64(&_counter);

La suggestion d'utiliser les fonctions / macros natives (c.-à-d. InterlockedExchangePointer, etc ... ainsi que de nombreuses autres fonctionnalités intéressantes que je ne connaissais pas, comme InterlockedXor64) est sérieusement entravée. par le fait que cela peut entraîner l’insertion d’un élément intrinsèque (au moins avec les paramètres de compilation par défaut) dans votre fonction C++/CLI gérée. Lorsque cela se produit, toute votre fonction sera compilée en tant que version native.

Et les versions gérées de Interlocked::* sont également utiles car vous n’avez pas à pin_ptr si la cible est dans un objet GC. Cependant, comme indiqué sur cette page, il peut être très pénible de trouver les incantations adéquates pour que cela fonctionne, en particulier lorsque vous souhaitez échanger, (c'est-à-dire) des pointeurs natifs eux-mêmes. Voici comment:

int i1 = 1, i2 = 2;

int *pi1 = &i1, *pi2 = &i2, *pi3;

pi3 = (int*)Interlocked::Exchange((IntPtr%)pi1, IntPtr(pi2)).ToPointer();

J'ai vérifié que cela fonctionnait correctement, malgré le manque de prise d'adresse (&) étrangement troublant sur le pointeur pi1. Mais cela a du sens, quand on y pense, car si la cible se déplace dans un hôte du GC, vous ne voudriez pas faire la chose ** habituelle en récupérant l’adresse <=> (native) du pointeur lui-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top