通过COM将对象从VBA传递到.NET时不一致
我定义了以下接口,以向COM公开.NET类:通过COM将对象从VBA传递到.NET时不一致,.net,vba,com,.net,Vba,Com,我定义了以下接口,以向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 v
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6A983BCC-5C83-4b30-8400-690763939659")]
[ComVisible(true)]
public interface IComClass
{
object Value { get; set; }
object GetValue();
void SetValue(object value);
}
此接口的实现非常简单:
[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与预期一致。然而,我在最后一行得到一个“objectrequired”运行时错误
为什么通过setter方法设置值有效,但通过属性设置失败?我需要做什么改变才能使物业按预期运行
编辑:我得到了一些有用的回答,所以我的补充问题是“这个问题会出现在用其他语言编写的COM客户端上,还是特定于VBA?”。您需要在最后一行使用Set关键字:
Set cc.Value = 555.555
您是否尝试过类似(vb有点生疏,您明白了):
您的接口将导出到类型库,如下所示:
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);
};
Dim cc As Object ' this one changed from ComClass
Set cc = New ComClass
...
cc.Value = 555.555
dispinterface图标类{
特性:
方法:
[id(00000000),propget]
变量值();
[id(00000000),propputref]/这似乎是tlbexp
和MS Advice使用如下延迟绑定调用的问题:
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);
};
Dim cc As Object ' this one changed from ComClass
Set cc = New ComClass
...
cc.Value = 555.555
您可以将其提前绑定,然后尝试更简单的修复:
Set cc.Value = CVar(555.555)
当我尝试调试失败时,出现编译错误:object required。您是否尝试将调试器附加到excel进程,并介入并查看其确切位置?不确定您指的是哪个调试器。如果我通过VS.net将excel作为外部程序启动来调试.net代码,我将无法到达设置部分的断点值属性,表示这是excel问题。如果你是说直接调试excel,我不知道从哪里开始-你能给我一些详细信息吗?谢谢。谢谢你提供的信息-不是我想要的答案:)那么这个问题只会发生在VBA客户端吗?我一直在通过VBA测试COM接口,但无法控制客户端将使用的语言。您真的必须支持变体吗?您真的必须支持早期绑定吗?您的问题中没有足够的信息来进行调用。我觉得早期绑定+intellisense使我的API的消费者更容易使用(因此支持调用更少!).至于支持变量(对象),考虑到我需要Value接受的类型,我可以指定Value是一个字符串,并对其进行适当的解释,但这对.NET客户端来说似乎很奇怪(可能并不奇怪,因为它是object…)。在任何情况下,您是否认为原始问题是VBA或更一般的COM问题?您的后期绑定建议有效,但CVar方法会产生与以前相同的错误(我尝试过使用和不使用Set关键字)。您知道我是否会遇到来自以不同语言编写的客户端的相同问题吗?例如,这是COM问题还是VBA问题?这是.Net COM互操作问题。您确定CVar
不会更改错误消息吗?我再次检查了CVar方法,但它肯定失败:(考虑到这是一个.NET COM互操作问题,并且其他客户端可能没有后期绑定选项,听起来我需要用getter/setter替换属性,或者更改属性类型。这个答案和nobugz的答案都非常有用。他的答案对问题的起因提供了更多的背景信息,so我已经把他的答案定为公认的答案——希望没问题。