.net - 通过 COM 将对象从 VBA 传递到 .NET 时不一致

标签 .net vba com

我定义了以下接口(interface)以向 COM 公开 .NET 类:

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6A983BCC-5C83-4b30-8400-690763939659")]
[ComVisible(true)]
public interface IComClass
{
    object Value { get; set; }

    object GetValue();

    void SetValue(object value);
}

这个接口(interface)的实现很简单:

[ClassInterface(ClassInterfaceType.None)]
[Guid("66D0490F-718A-4722-8425-606A6C999B82")]
[ComVisible(true)]
public class ComClass : IComClass
{
    private object _value = 123.456;

    public object Value
    {
        get
        {
            return this._value;
        }

        set
        {
            this._value = value;
        }
    }

    public object GetValue()
    {
        return this._value;
    }

    public void SetValue(object value)
    {
        this._value = value;
    }
}

然后我使用 RegAsm 注册了它,并尝试通过以下代码从 Excel 中调用它:

Public Sub ComInterop()

    Dim cc As ComClass
    Set cc = New ComClass

    cc.SetValue (555.555)

    valueByGetter = cc.GetValue 
    valueByProperty = cc.Value 

    cc.Value = 555.555 

End Sub

当我单步执行此代码时,valueByGetter = 555.5555 和 valueByProperty = 555.555 符合预期。但是,我在最后一行收到“需要对象”运行时错误。

为什么通过 setter 方法设置值有效,但通过属性设置失败?我必须更改什么才能使属性按预期工作?

编辑:我收到了一些有用的回复,所以我的额外问题是“这个问题会出现在用其他语言编写的 COM 客户端中,还是特定于 VBA?”。

最佳答案

你的接口(interface)是这样导出到类型库的:

dispinterface IComClass {
    properties:
    methods:
        [id(00000000), propget]
        VARIANT Value();
        [id(00000000), propputref]             // <=== problem here
        void Value([in] VARIANT rhs);
        [id(0x60020002)]
        VARIANT GetValue();
        [id(0x60020003)]
        void SetValue([in] VARIANT Value);
};

问题是 Value 属性 setter ,它被声明为 propputref 而不是 propput。完全不同的是 COM 中一个令人讨厌的一致性问题,这是由它支持默认属性引起的。这就是您必须在 VBA 中使用 Set 关键字的原因。问题是:您没有在 VBA 代码中传递对象,即使 .NET 需要一个对象。

经过一番研究后,我发现没有针对此问题的现成解决方案。 Let 关键字可能在 VBA 中起作用的可能性很小,我没有尝试过。唯一的半途而废的修复是强制后期绑定(bind),而不是 ComInterfaceType.InterfaceIsDual 使用 ComInterfaceType.InterfaceIsIDispatch。或者避免使用“object”。

关于.net - 通过 COM 将对象从 VBA 传递到 .NET 时不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2539338/

相关文章:

c# - AmyuniPDF 以错误的字体(特殊字符)打印 PDF 文档

c# - System.Windows.Forms.Screen.DeviceName 在 Windows XP 上产生垃圾

vba - 复制工作表的数据源

vba - 格式化用户窗体中的文本框

c++ - 是否有任何 ATL 支持的宏来检查 hresults 并返回值?

.net - 在 Entity Framework 中包含多个导航属性的语法是什么?

c# - 如何使用不同的 set 和 get 重载 [] 运算符?

delphi - TScriptControl - 类未注册

c++ - 在 PrintOut OLE 函数中设置事件打印机

.net - 为什么我无法在 .NET 中使用 TBIMP 创建的互操作程序集?