我遇到了一个问题,我认为这与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标记了ID,并且数字未更改)。所以现在演员阵容成功了。

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

最佳答案

COM对象“住”在他们的公寓中,代理也是如此。跨单元边界传递“原始” COM接口指针(有时可能会读为“跨线程边界”)是使COM接口指针在无访问冲突和崩溃的情况下仍可正常运行的典型原因,但未能完成预期的任务,包括无法通过QueryInterface返回另一个接口指针。

有了COM接口指针后,您有兴趣在COM单元和各个线程中使用它,并在该线程上获得了指针。

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


Passing COM object between threads with C#
Understanding Classic COM Interoperability With .NET Applications

10-02 01:37
查看更多