c# – 我是在调用.NET对象还是COM对象?

前端之家收集整理的这篇文章主要介绍了c# – 我是在调用.NET对象还是COM对象?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
今天出现了一个有趣的问题.假设我有一个.NET对象,它实现了某个接口IMyInterface并且也是COM Visible.

现在,我从其ProgID加载类型并强制转换为强类型接口,如下所示:

IMyInterface objEarlyBound = null;
Type t = Type.GetTypeFromProgID("My.ProgId");
objLateBound = Activator.CreateInstance(t);

objEarlyBound= (IMyInterface)objLateBound;

objEarlyBound.Method();

如果我执行上面的代码,当objEarlyBound.Method()执行时,我是调用COM对象还是直接调用.NET对象?我怎样才能证明这种或那种方式?

解决方法

你无论如何都无法证明这一点 – 这是一个故意隐瞒你的内部实现选择.

objEarlyBound和objLateBound需要具有相同的标识,即==对它们将返回true.因此,从它们中的每一个,您总是可以获得另一个,并且同样支持它们支持的任何其他接口,并且如果您将它们中的任何一个分配给对象.但这并没有证明什么.

如果您直接引用包含通过COM公开的类的程序集作为My.ProgId,您可以说:

IMyInterface objEarlyBound = new MyClassExposedThroughCOM();

此时,根本不需要CLR的COM支持.但是,然后您可以将该对象传递给某个外部COM库,此时CLR将创建一个CCW以与该对象关联.并且已经完成了一次,对于任何给定的CLR对象,它总是可以回到相同的CCW.

因此,为了将它与您的示例相关联,您可以在COM对象周围使用RCW,将其转换为接口,此时CLR可以(据我们所知)查询特殊的内部COM接口,如果找到,允许它获取内部CLR对象,从而完全绕过COM.如果它在任何时候需要回到CCW,它可以这样做,因为它必须能够在另一个方向工作时随时做到这一点.

我已经尝试在手工实现的C COM对象的QueryInterface函数中放置一个断点,以查看CLR查询内容.基本上它会尝试很多东西,其中一些我无法立即识别,所以很可能会“嗅探”一个CLR对象.这样做是有意义的,以避免疯狂的COM三明治情况,其中CLR参考指向RCW,其指向CCW,其指向CLR对象.通过使CLR引用直接指向CLR对象,可以清楚地简化这一点.

实际上现在我想一想,它不需要查询来找到它:它有一个它之前生成的CCW全局表,所以它可以在那里查找任何新的IUnknown. COM对象必须始终为IUnknown返回完全相同的地址,以便它可用于对象标识比较.因此,CLR始终可以识别它正在实现的COM对象,并获取相应的CLR对象.

顺便说一下,所有这些讨论都假设COM对象正在进行中.如果它是在进程外,那么情况就完全不同了;每个进程都有自己的CLR实例,因此也可以使用进程间编组的COM实现.

猜你在找的C#相关文章