如何在 C++/CLI 中的静态变量上使用 System::Threading::Interlocked::Increment?

发布于 2024-07-09 23:55:11 字数 290 浏览 6 评论 0原文

我想在垃圾收集类中保留一个静态计数器,并使用 Interlocked::Increment 递增它。 执行此操作的 C++/CLI 语法是什么?

我一直在尝试以下变化,但到目前为止没有运气:

ref class Foo
{
   static __int64 _counter;

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

};

I would like to keep a static counter in a garbage collected class and increment it using Interlocked::Increment. What's the C++/CLI syntax to do this?

I've been trying variations on the following, but no luck so far:

ref class Foo
{
   static __int64 _counter;

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

};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

王权女流氓 2024-07-16 23:55:11

您需要使用跟踪参考到您的 < code>_int64 值,使用 % 跟踪参考符号:

ref class Bar
{
    static __int64 _counter;

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

You need to use a tracking reference to your _int64 value, using the % tracking reference notation:

ref class Bar
{
    static __int64 _counter;

    __int64 Next()
    {
        __int64 %trackRefCounter = _counter;
        return System::Threading::Interlocked::Increment(trackRefCounter);
    }
};
若有似无的小暗淡 2024-07-16 23:55:11

只需删除地址运算符:

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

在 C++/CLI 中,与 C++ 一样,没有用于按引用传递的特殊符号。

或者您可以使用本机函数 InterlockedIncrement64 (#include)

return ::InterlockedIncrement64(&_counter);

Just remove the address-of operator:

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

In C++/CLI, like C++, there is no special notation for passing by reference.

or you could use the native function, InterlockedIncrement64 (#include <windows.h>)

return ::InterlockedIncrement64(&_counter);
百变从容 2024-07-16 23:55:11

建议使用本机函数/宏(即InterlockedExchangePointer等)...加上很多我不知道的很酷的函数/宏,例如InterlockedXor64< /code>) 受到严重阻碍,因为这样做可能会导致内部函数(至少在默认编译器设置下)被放入托管 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 主机中移动,您就不会希望通过抓取 &< 来执行通常的 ** 操作。 /code> 指针本身的(本机)地址。

The suggestion to use the native functions/macros (i.e. InterlockedExchangePointer, etc... plus a lot of cool ones I didn't know about such as InterlockedXor64) is severely hampered by the fact that doing so can cause an intrinsic (at least with the default compiler settings) to be dropped into your managed C++/CLI function. When this happens, your whole function will be compiled as native.

And the managed versions of Interlocked::* are also nice because you don't have to 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 incantations for getting it to work, especially when you want to swap, (i.e) native 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 verified that this does work properly, despite the suspiciously unnerving lack of address-taking (&) on the pi1 pointer. But it makes sense, when you think about it because if the target is moving about in a GC host, you wouldn't want to do the usual ** thing by grabbing the & (native) address of the pointer itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文