Mot*_*tti 1 .net c# com interop
我已阅读文档,Marshal.GetIUnknownForObject并说:
Marshal.Release完成指针后,始终使用减少引用计数.
我写了,我通过.NET中使用COM对象的测试解决方案,我看到与工作时的包装,以我的COM对象既不Marshal.GetIUnknownForObject也不Marshal.Release引起AddRef或Release我的COM对象的方法被调用.
那是怎么回事?
等一下,我想我已经明白了.你正在创建一个COM对象,然后你在这个COM对象周围创建一个运行时可调用包装器,然后你要求运行时可调用包装器为它的朋克,然后你想知道为什么在那个朋克上调用release不会调用你的发布?这总结了你的问题吗?
如果是这样,你可能已经在问题中提到了所有这些细节而不是让我们猜测.
好吧,为什么你认为它会调用你的版本?它将调用运行时可调用包装器的Release .包装器包裹你的对象; 这就是为什么它被称为包装器.运行时可调用包装并不需要对AddRef和每次释放你的对象是被addref'd并发布了!为什么会这样?它需要让你的对象保持活着,它已经有你的对象的引用 ; 这足以使包裹的物体保持活力.为什么不必要的工作?
当你只有一个COM对象周围的运行时可调用包装器时,你应该合理地期望对象的ref计数在对象的整个生命周期内是不变的.运行时接受一次ref,当RCW最后一次被垃圾收集或以其他方式释放时,它会释放ref并且对象会自行删除.
想想这样.假设你说:
foo->bar = blah;
blah->AddRef();
Run Code Online (Sandbox Code Playgroud)
blah得到addref'd因为foo-> bar有引用它.现在你说:
abc->def = foo;
foo->AddRef();
Run Code Online (Sandbox Code Playgroud)
这增加了foo的参考.它是否添加了参考等等?当然不是.为什么会这样?foo有一个基础; foo被abc保持活着的事实与blah无关.
这里也是一样的.你有:
wrapper = new RCW();
wrapper->wrapped = yourobject;
yourobject->AddRef();
Run Code Online (Sandbox Code Playgroud)
这为你提供了一个参考.现在,如果你有
wrapper->QI(IUnknown, &punk)
Run Code Online (Sandbox Code Playgroud)
它不会给你底层对象的朋克,它会给你包装器的朋克.如果你说
punk->AddRef();
Run Code Online (Sandbox Code Playgroud)
如果没有addref底层对象,它会添加包装器.
| 归档时间: |
|
| 查看次数: |
2153 次 |
| 最近记录: |