我遇到了一个问题,我认为这与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