【问题标题】:Check Value of .NET Handle ^检查 .NET 句柄的值 ^
【发布时间】:2011-11-30 01:51:42
【问题描述】:

这是我的情况:

我在 C++/CLI 层中有 .NET 包装对象,其中包含指向非托管 C++ 对象的指针。我已经实现了终结器,以便它删除垃圾收集上的包装对象指向的非托管内存并将指针设置为 null。

问题出在这里

我正在查看 .NET 包装器对象的终结器,它被调用两次并尝试两次删除相同的内存,这表明我以某种方式创建了 2 个超出范围的 .NET 包装器对象,并且当我仍然期望包装器对象在范围内时被垃圾收集(这些包装器对象正在传递给 VB.NET 应用程序)。

这是我的问题:

我是否可以检查句柄值,以便我可以确认包装对象的创建位置(复制或其他)?目前我正在查看句柄值(EG - 0x0014fe80),但我看到创建对象、添加到集合和删除对象时的 3 个不同值。所以我不确定GC是否只是在移动东西并且这是同一个对象,或者我是否真的看到3个不同的对象引用了相同的非托管内存。如果可能,我想解决重复的对象副本,但我知道我可能想要实现某种智能指针,这样就不会发生这种情况。

谢谢, 伊恩

【问题讨论】:

  • 不,垃圾收集器在压缩堆时会更新它。跟踪对象的一种简单方法是在构造函数中给它们一个数字。理想情况下,本机指针值就足够了:)
  • 好的,但是如果我有这样的东西怎么办:Public Sub handle_obj_callback(Wrap_Class^ obj)`dat_member = obj`End Sub我也从不调用 dat_member 上的构造函数,但它与参数的类型相同,所以我只是设置它。然后我有两个指向同一个非托管内存的 .NET 对象,对,所以我无法区分它们?
  • 抱歉,这太糟糕了,我不知道如何在这些 cmets 中发布代码。但本质上,我有一个 VB.NET 类,其中包含一个我从不调用构造函数的成员。我对它所做的所有事情都是将其设置为从 C++/CLI 库传递给我的对象的值。所以我最终得到了 2 个引用相同非托管内存的 NET 对象。
  • 您正在混合使用 vb.net 和 c++/cli 语法,难以理解。但是不,您应该只设置对同一对象的两个引用。终结器只在两个引用消失后运行一次。

标签: interop c++-cli mixed-mode handles


【解决方案1】:

看看this question
Herescoped_ptr 的一个实现,它是不可复制的,并且具有非托管对象的自动释放机制,作者@Ben Voigt

【讨论】:

    【解决方案2】:

    是的,我最终将 auto_ptr 类修改为共享指针,以确保非托管内存仅通过智能指针终结器删除一次。我假设我做了与所有其他实现类似的事情;我在 auto_ptr 模板类中创建了一个静态字典,使用本机指针值作为键,每次调用终结器以更新每个项目的计数或删除内存时都会检查它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 2011-04-27
      • 1970-01-01
      • 2015-03-15
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多