C# 为什么我在尝试COM聚合时遇到ExecutionEngineeException
我正在尝试使用以下代码聚合COM对象(外部未知)中的.NET对象:C# 为什么我在尝试COM聚合时遇到ExecutionEngineeException,c#,.net,com,C#,.net,Com,我正在尝试使用以下代码聚合COM对象(外部未知)中的.NET对象: Object obj = ... // some ComVisible .NET object var comObj = (IMyComInterface)Activator.CreateInstance(Type.GetTypeFromProgID("some.progid")); var unknown = Marshal.GetIUnknownForObject(comObj); var innerUnknown
Object obj = ... // some ComVisible .NET object
var comObj = (IMyComInterface)Activator.CreateInstance(Type.GetTypeFromProgID("some.progid"));
var unknown = Marshal.GetIUnknownForObject(comObj);
var innerUnknown = Marshal.CreateAggregatedObject(unknown, obj);
// This is where the ExecutionEngineException is thrown.
var aggObj = Marshal.GetObjectForIUnknown(innerUnknown);
// Make outer object aware of our dotnet object, say.
comObj.DotNetObj = aggObj;
Marshal.Release(unknown);
...
这个代码有什么“明显”的错误吗?这个例外让我没有什么可继续的了。同样令人恼火的是,异常并不总是发生,尽管它经常发生。
有没有其他方法可以做到这一点?(即将innerUnknown IntPtr封送到我的COM对象)
注意:我必须以框架的版本2为目标,还没有尝试过版本4,据我所知,我完全是最新的。要回答这个问题,它失败的原因是innerUnknown是错误的未知。该方法旨在获取COM IUnknown的活动RCW,但此IUnknown是托管对象的COM可调用包装器 在任何情况下,外部对象都需要
innerUnknown
指针。如果你给它一个你正在尝试的,你会在QueryInterface中得到一个堆栈溢出
在上面的示例中,.Net对象认为它已被COM对象聚合,但COM对象不知道。假设它是您的COM对象,您需要为它指定innerUnknown,然后实现一个委托IUnknown(如果您还没有)。您不需要调用GetObjectForIUnknown
然而,你是在倒退。通常的方法是COM对象调用CoCreateInstance,将自身作为外部未知对象传递。然后运行库为您调用CreateAgregateObject
如果希望.Net对象聚合COM对象,则应从RCW继承。这将创建COM对象作为聚合对象,将.Net内部未知传递给CoCreateInstance。但它必须是支持聚合的对象
如果希望COM对象聚合.Net对象,则必须使用能够聚合.Net对象的COM对象。典型的例子是ADO聚合OLEDB提供程序、ADSI聚合ADSI扩展、WMI(我想)。但是它必须由对象支持,您不能告诉任何旧对象来聚合您。通常,它由另一个调用CoCreateInstance的对象发生,CoCreateInstance由.Net运行时处理,它将为您调用CreateAggregateObject,并将innerUnknown传递回调用方。Try
comObject.DotNetObj=innerUnknown代码>。调用GetObjectForIUknown
是不必要的。感谢您的回答,它确实起了作用。我确实必须更改ComImported接口,将DotNetObj的类型设置为IntPtr(而不是Object),并封送为SysInt。我真希望我得到的异常能有点帮助,文档也是如此。我意识到代码有点落后,这是我遇到的另一个问题的实验。