在C#中传递继承自泛型的对象会导致使用IDispatch进行强制转换异常

时间:2016-02-16 17:14:34

标签: c# .net exception com marshalling

我有一个我想做的COM电话

[DispId(163)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = 
  MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.IDispatch)]
object CreatePropertyManagerPage
  ([MarshalAs(UnmanagedType.BStr), In] string Title,
   [In] int Options,
   [MarshalAs(UnmanagedType.IDispatch), In] object Handler,
   [In, Out] ref int Errors);

处理程序属性是导致我出问题的属性。如果我传入一个继承自

的对象
public abstract class PmpBase<TMacroFeature,TData> : IPropertyManagerPage2Handler9

然后我得到一个InvalidCastException。但是,如果我删除泛型并传递一个继承自

的类
public abstract class PmpBase : IPropertyManagerPage2Handler9

通过对文件中的类型进行硬编码,然后对象进入调用。我可以通过

复制相同的发现
new DispatchWrapper(foo)

其中 foo 是派生自通用(失败)和非通用(通过)版本的类的实例。

我对COM一无所知,只是尝试将自动化界面用于solidworks。我想做一些不可能的事情。我没有发现任何明显的文章将泛型与COM的错误相关联。

1 个答案:

答案 0 :(得分:0)

我无法解释为什么会出现问题,但解决方案非常简单。我为我试图传递给COM的接口创建了一个代理类。

public class PropertyManagerPage2Handler9Wrapper : IPropertyManagerPage2Handler9
{
    readonly IPropertyManagerPage2Handler9 _Implementation;

    public PropertyManagerPage2Handler9Wrapper(IPropertyManagerPage2Handler9 implementation)
    {
        _Implementation = implementation;
    }

    public void AfterActivation()
    {
        _Implementation.AfterActivation();
    }

    public void OnClose(int Reason)
    {
        _Implementation.OnClose(Reason);
    }

    public void AfterClose()
    {
        _Implementation.AfterClose();
    }

    <snip>
}

并将包装器传递给COM函数而不是原始实例。然后没有阶级演员例外。

var propertyManagerPage = SwApp.CreatePropertyManagerPage
     (_Name, options, new PropertyManagerPage2Handler9Wrapper(this), ref errors);

而不是

var propertyManagerPage = SwApp.CreatePropertyManagerPage
    (_Name, options, this, ref errors);