gpt4 book ai didi

c# - 为什么 Marshal.Release 不对我的 COM 对象调用 Release?

转载 作者:太空宇宙 更新时间:2023-11-03 17:59:07 27 4
gpt4 key购买 nike

我已阅读 Marshal.GetIUnknownForObject 的文档它说:

Always use Marshal.Release to decrement the reference count once you have finished with the pointer.

我用 COM 对象编写了一个测试解决方案,我通过 .NET 使用它,我在使用 wrapper 时看到了这一点对于我的 COM 对象,Marshal.GetIUnknownForObjectMarshal.Release 都不会导致我的 COM 对象的 AddRefRelease 方法被称为。

这是怎么回事?

最佳答案

等一下,我想我明白了。您正在制作一个 COM 对象,然后围绕该 COM 对象制作一个运行时可调用包装器,然后您向运行时可调用包装器询问它的 punk,然后您想知道为什么在那个 punk 上调用 release 不调用你的释放?这是否总结了您的问题?

如果是这样,您可能已经在问题中提到了所有这些细节,而不是让我们猜测。

那么,您认为为什么它会调用您的 版本?它将调用运行时可调用包装器的 Release 。包装器包装您的对象;这就是为什么它被称为包装器。每次添加和释放对象时,运行时可调用包装器不需要添加和释放对象!为什么会这样?它需要让您的对象保持事件状态并且它已经在您的对象上有一个引用;这足以使包裹的对象保持事件状态。为什么要做不必要的工作?

当您只有一个围绕 COM 对象的运行时可调用包装器时,您应该合理地期望该对象的引用计数在该对象的整个生命周期内保持不变。运行时获取一个 ref 一次,当 RCW 最后一次被垃圾回收或以某种其他方式释放时,它释放该 ref 并且对象删除自身。

这样想。假设你说:

foo->bar = blah;
blah->AddRef();

blah 得到 addref',因为 foo->bar 有一个对它的引用。现在你说:

abc->def = foo;
foo->AddRef();

这为 foo 添加了一个 ref。它是否为 blah 添加了一个引用?当然不是。为什么会这样? foo 有一个 blah 的引用; foo 被 abc 保持存活的事实与 blah 无关。

这里也是一样。你有:

wrapper = new RCW();
wrapper->wrapped = yourobject;
yourobject->AddRef();

这会为您的对象添加一个引用。现在如果你有

wrapper->QI(IUnknown, &punk)

这并没有让您对底层对象产生兴趣,而是对包装器产生了兴趣。如果你说

punk->AddRef();

它不对底层对象添加引用,它对包装器进行添加引用。

关于c# - 为什么 Marshal.Release 不对我的 COM 对象调用 Release?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4522808/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com