在 C# 中传递从泛型继承的对象会导致 IDispatch 发生强制转换异常

本文关键字:IDispatch 异常 转换 对象 继承 泛型 | 更新日期: 2023-09-27 18:34:54

我想进行 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

然后我得到一个无效的投射异常。但是,如果我删除泛型并传递一个继承自

public abstract class PmpBase : IPropertyManagerPage2Handler9

通过对文件中的类型进行硬编码,对象将传递到调用中。我可以通过做

new DispatchWrapper(foo)

其中foo是类的一个实例,它派生自泛型(它失败(和非泛型(它通过(版本。

我对COM的了解为零,只是尝试使用自动化接口进行solidworks。我是否试图做一些不可能的事情。我还没有找到任何将泛型与 COM 错误相关联的明显文章。

在 C# 中传递从泛型继承的对象会导致 IDispatch 发生强制转换异常

我无法解释为什么会出现问题,但解决方案非常简单。我为尝试传递给 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);