3

我遇到了一个我认为与 CLR 与 COM 对象互操作的方式有关的问题,但我希望这里的一些人可以提供更多的见解。我想为这个问题的模糊性提前道歉,不幸的是我正在与一个有点不透明的系统集成。

考虑以下代码:

class Foo
{
    private IComInterface comObject;

    Foo(IServiceProvider provider)
    {
        this.comObject = serverProvider.GetService(typeof(ISomeService)) as IComInterface;
        Debug.Assert(this.comObject != null); // comObject is *not* null here
    }

    void Bar()
    {
        IOtherComInterface otherInterface = this.comObject as IOtherComInterface;
        Console.WriteLine(otherInterface == null);
    }
}

COM 互操作类型嵌入在我的程序集中,该程序集由另一个程序作为插件加载。当我第一次创建 的实例时Foo,服务提供者(由程序提供)提供的 COM 对象是非空的。但是,当我立即调用 时Bar(),转换为IComOtherInterface不起作用:该方法打印“true”。

不过,我的问题是,在加载了其他一些插件后,Bar()再次调用会打印"false"。我已经验证它是同一个实例Foo,实际上是同一个实例comObject(我使用调试器用 ID 标记了两者,并且数字没有改变)。所以现在演员阵容成功了。

所以我的问题是:这怎么可能?是否有可能存储的对象comObject实际上是通过同一个 RCW 第二次包装一个新的本机 COM 对象?加载其他程序集是否可能以某种方式改变了的类型标识,IOtherComInterface以便演员现在可以工作?其他一些我实际上无法理解的疯狂可能性?

4

1 回答 1

3

COM 对象“生活”在他们的公寓里,他们的代理也是如此。跨单元边界传递“原始”COM 接口指针(有时可能读作“跨线程边界”)是 COM 接口指针在没有访问冲突和其他情况下崩溃的典型原因,但在预期任务上失败,包括未能通过 . 返回另一个接口指针QueryInterface

一旦你有了一个 COM 接口指针,你就有兴趣在 COM 单元和相应的线程中使用它,你在其中获得了指针。

要在单元/线程之间传递指针,您需要采取额外的步骤(在原始线程上编组指针,然后在目标线程上解组)。也可以看看:

于 2014-07-15T08:11:07.353 回答