C#中的奇怪COM对象行为

时间:2014-07-15 07:17:59

标签: c# com com-interop rcw

我遇到了一个问题,我认为这与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的类型标识,以便现在可以使用强制转换?其他一些我无法理解的疯狂可能性?

1 个答案:

答案 0 :(得分:3)

COM对象在他们的公寓中“活着”,他们的代理也是如此。在公寓边界上传递“原始”COM接口指针(有时可能跨越线程边界读取)是使COM接口指针在没有访问冲突和其他方面崩溃仍然可操作的典型原因,但是在预期任务上失败,包括无法通过QueryInterface返回另一个接口指针。

一旦有了COM接口指针,您就有兴趣在COM公寓和相应的线程中使用它,在那里获得指针。

要在公寓/线程之间传递指针,您需要采取其他步骤(将指针封送在原始线程上,然后在目标线程上解组)。另见: