在 C++/CLI 场景中调用 GC::KeepAlive 的便捷方式?

发布于 2024-07-17 13:59:59 字数 1304 浏览 4 评论 0原文

我正在使用 C++/CLI 编写一些托管包装器。 问题是,当我使用对象中的非托管成员时,GC 有时会处置该对象。 (我认为这种行为很疯狂,但这是另一个话题)。 有关更多详细信息,请参阅:

终结器在其对象仍在使用时启动 http://blogs.msdn.com/cbrumme/archive/ 2003/04/19/51365.aspx

我正在寻找一种方便的调用方式:

GC::KeepAlive(this);

在每个方法的末尾。 对于普通的旧 void 方法来说,这很容易,但对于返回值的方法来说,这就有点棘手了。

int ComputeInt() {
   return m_unmanagedMember->LongRunningComputation();
}

必须变成:

int ComputeInt() {
   int tmp = m_unmanagedMember->LongRunningComputation();
   GC::KeepAlive(this);
   return tmp;
}

这对我来说看起来有点难看。

我考虑了一个在 dtor 中调用 GC::KeepAlive 的保护类,但这会在每个方法中引发 ctor 和 dtor 调用,这似乎有点过多。

有没有可用的 C++ 魔法可以让我避免使用 temp 变量?

编辑

我意识到 try + finally 可以为我解决问题,即:

int ComputeInt() {
   try {
      return m_unmanagedMember->LongRunningComputation();
   } finally {
      GC::KeepAlive(this);
   }
}

最后,我实现了一个宏来处理这个问题:

#define KEEPALIVE_RETURN(x) try {\
    return x;\
} finally { System::GC::KeepAlive(this); }

I'm writing some managed wrappers using C++/CLI. The problem is that the GC sometimes disposes the object while I'm using unmanaged members from it. (I think this behaviour is insane but this is another topic). For more details see:

Finalizer launched while its object was still being used
http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx

What I'm looking for is a convenient way to call:

GC::KeepAlive(this);

at the end of every method. For plain old void methods it's easy enough but for methods returning values its a bit more tricky.

int ComputeInt() {
   return m_unmanagedMember->LongRunningComputation();
}

would have to be turned into:

int ComputeInt() {
   int tmp = m_unmanagedMember->LongRunningComputation();
   GC::KeepAlive(this);
   return tmp;
}

This looks a bit ugly to me.

I considered a guard class that calls GC::KeepAlive in the dtor but that would incur a ctor and dtor call in every method which seems a bit excessive.

Is there any C++ magic available that would let me avoid the temp variable?

Edit

I realized that a try + finally would do the trick for me, i.e:

int ComputeInt() {
   try {
      return m_unmanagedMember->LongRunningComputation();
   } finally {
      GC::KeepAlive(this);
   }
}

In the end, I implemented a macro to handle this:

#define KEEPALIVE_RETURN(x) try {\
    return x;\
} finally { System::GC::KeepAlive(this); }

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

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

发布评论

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

评论(1

横笛休吹塞上声 2024-07-24 13:59:59

怎么样(不是真正检查语法)

template<class RType>
const RType& KeepAliveRet(Object^ o, const RType& ret)
{
    GC::KeepAlive(o);
    return ret;
} 


int ComputeInt() {
   return KeepAliveRet(this, m_unmanagedMember->LongRunningComputation());
}

How about something like (not really checking syntax)

template<class RType>
const RType& KeepAliveRet(Object^ o, const RType& ret)
{
    GC::KeepAlive(o);
    return ret;
} 


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