Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我在尝试COM聚合时遇到ExecutionEngineeException_C#_.net_Com - Fatal编程技术网

C# 为什么我在尝试COM聚合时遇到ExecutionEngineeException

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

我正在尝试使用以下代码聚合COM对象(外部未知)中的.NET对象:

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。我真希望我得到的异常能有点帮助,文档也是如此。我意识到代码有点落后,这是我遇到的另一个问题的实验。