Tim*_*ong 7 .net c# com-interop
今天出现了一个有趣的问题.假设我有一个.NET对象,它实现了某个接口IMyInterface并且也是COM Visible.
现在,我从其ProgID加载类型并转换为强类型接口,如下所示:
IMyInterface objEarlyBound = null;
Type t = Type.GetTypeFromProgID("My.ProgId");
objLateBound = Activator.CreateInstance(t);
objEarlyBound= (IMyInterface)objLateBound;
objEarlyBound.Method();
Run Code Online (Sandbox Code Playgroud)
如果我执行上面的代码,当objEarlyBound.Method()执行时,我是调用COM对象还是直接调用.NET对象?我怎样才能证明这种或那种方式?
无论哪种方式,您都无法证明太多 - 这是故意向您隐瞒的内部实现选择。
objEarlyBound并objLateBound要求具有相同的身份,即==它们上都会返回true。因此,您始终可以从它们中的每一个获取另一个,对于它们支持的任何其他接口也是如此,如果您将它们中的任何一个分配给object. 但这并不能证明什么。
如果您直接引用包含通过 COM 公开的类的程序集My.ProgId,您可以说:
IMyInterface objEarlyBound = new MyClassExposedThroughCOM();
Run Code Online (Sandbox Code Playgroud)
此时根本不需要 CLR 的 COM 支持。但是,您可以将该对象传递给某个外部 COM 库,此时 CLR 将创建一个 CCW 来与该对象关联。完成一次后,对于任何给定的 CLR 对象,它始终可以返回相同的 CCW。
因此,为了将其与您的示例联系起来,您从围绕 COM 对象的 RCW 开始,将其转换为接口,此时 CLR 可以(据我们所知)查询特殊的内部 COM 接口,如果找到该接口,允许它获取内部 CLR 对象,从而从此完全绕过 COM。如果它在任何时候需要返回《特定常规武器公约》,它都可以这样做,因为它必须能够在向另一个方向工作时随时这样做。
我尝试在手动实现的 C++ COM 对象的 QueryInterface 函数中放置一个断点,以查看 CLR 查询的内容。基本上它会尝试很多事情,其中一些我无法立即识别,因此它很可能是在“嗅探”其他 CLR 对象。这样做是有意义的,以避免出现疯狂的 COM 三明治情况,其中 CLR 引用指向 RCW,RCW 指向 CCW,CCW 指向 CLR 对象。通过让 CLR 引用直接指向 CLR 对象,可以明显简化这一点。
实际上现在我想了一下,它不需要查询来找出这一点:它有一个之前生成的 CCW 全局表,因此它可以IUnknown在其中查找任何新的内容。COM 对象必须始终返回完全相同的地址,IUnknown以便可以将其用于对象身份比较。因此,CLR 始终可以识别它自己实现的 COM 对象,并获取相应的 CLR 对象。
顺便说一下,所有这些讨论都假设 COM 对象是进程内的。如果是进程外的话,情况就完全不同了;每个进程都有自己的 CLR 实例,因此也可以使用进程间编组的 COM 实现。
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |