【问题标题】:Passing an object in C# that inherits from a generic causes a cast exception with IDispatch在 C# 中传递从泛型继承的对象会导致 IDispatch 发生强制转换异常
【发布时间】:2016-05-28 02:32:52
【问题描述】:

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

Handler 属性是导致我出现问题的原因。如果我传入一个继承自

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

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

的类
public abstract class PmpBase : IPropertyManagerPage2Handler9

通过硬编码文件中的类型,然后对象传递到调用中。我可以通过这样做来复制相同的发现

new DispatchWrapper(foo)

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

我对 COM 的了解为零,只是尝试使用 Solidworks 的自动化接口。我是否正在尝试做一些不可能的事情。我没有发现任何将泛型与 COM 错误相关联的明显文章。

【问题讨论】:

  • 很不清楚你是如何从一个抽象类声明变成一个作为 Handler 参数传递的具体对象。 COM 不支持泛型。
  • 我说我传入的实例来自一个继承自抽象类的具体类。当您说 COM 不支持泛型时,您的意思是任何从具体类型继承的类都不受支持,或者将 com 接口声明为泛型是不受支持的。
  • handler 参数实际上是在寻找实现的接口 IPropertyManagerPage2Handler9。我可能只是制作一个不涉及通用并且可能解决问题的包装代理。明天试试。
  • 代理技术有效。我将其添加为答案。我仍然不明白为什么它会有所作为。

标签: c# .net exception com marshalling


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多