【问题标题】:gcroot has no valuegcroot 没有价值
【发布时间】:2011-09-24 06:45:32
【问题描述】:

我对非托管代码中的托管对象有一个奇怪的问题。我有这个桥接 C++ 和 C# 代码的 C++/CLI 模块。我有这样的结构:

template <class T>
struct ManagedReference
{
  gcroot<T^> addonHost;
}

现在,有时我会创建此托管引用的实例并设置 addonHost。一切都很好,我可以使用手柄。

但是,在某些情况下(恐怕需要大量上下文描述)该值无法评估:

在这种情况下,使用 addonHost 调用方法会导致“找到的入口点”异常。

从截图中可以看出,这不是两个不同的实例,两个不同的句柄。是一样的。我不明白在某些情况下如何不评估“价值”。也许我怎么能抓住它。因为它不为空。

我还应该提到的是,我有几个gcroot&lt;T&gt;,除了一个gcroot&lt;System::String&gt;之外,他们都有这个问题。

更新

这是调试器在执行期间显示的内容。该对象被创建并可用,然后在某个时候,该值“消失”,并且在下一次调用时它仍然存在。但这是非常可重复的。这不是随机的。

handle  0x0E1618EC  void*
 value  0x106396d8 { m_host=0x10638e04 }    <-- object is available here

handle  0x0E1618EC  void*
 value  0x1020e558 { m_host=0x1020e4f0 }    <-- object moved in memory

handle  0x0E1618EC  void*
 value                                      <-- no value here

handle  0x0E1618EC  void*
 value  0x1020e558 { m_host=0x1020e4f0 }    <-- object 'is back'

【问题讨论】:

  • 这是什么 gcroot 类? Microsoft 有一个 _handle,不是句柄,也没有值。
  • 调试器可能无法读取某些对象类型的值(被编译为优化的、调试器不知道的本地对象的 dll),你检查过这个吗?
  • @hans,这是微软的gcroot。是的,它有一个 _handle,但调试器显示了一个 handle 和一个 value,正如您从屏幕截图中看到的那样。当然你也可以自己试试
  • @yochai,如果只是调试器没有显示value,我不会启动这个线程;问题是条件pInstance &amp;&amp; pInstace-&gt;addonHost 评估为true,因此会发生类似pInstace-&gt;addonHost-&gt;CallMethod() 的调用,然后我得到一个“找到的入口点”异常。
  • 嗯,我做到了。你应该检查你的 autoexp.dat

标签: exception visual-c++ c++-cli handle mixed-mode


【解决方案1】:

也许初始化gcroot 会有所帮助。试试:

template <class T>
struct ManagedReference
{
  gcroot<T^> addonHost;
  ManagedReference() : addonHost(nullptr) {}
};

【讨论】:

  • 只是为了对想法开放,我已经尝试过了,但当然没有任何帮助。 addonHost 在创建实例后立即初始化,我可以在大多数情况下使用它的值。
  • @Marius:所以您期望pInstance-&gt;addonHost 应该始终正确设置(应该始终在if 语句中评估为真)?
  • 是的,因为,你看,在初始化之后,这段代码被调用了好几次,而且在某些情况下,没有“找到”值(我不知道怎么说) ;但在那之后的下一个电话,它再次工作
  • @Marius:只是调试器行为不端(看不到值),还是程序有时也会得到不好的结果? gcroot 变量和监视表达式存在一些已知的调试器问题。
  • 是的,不仅仅是调试器;我是否使用调试器运行并不重要,无论是调试还是发布配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
相关资源
最近更新 更多