鉴于以下C#类:
namespace ComTest { [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] [Guid("A1D11BE5-40A1-4566-A1CA-418ABC76017C")] public interface IThing { [DispId(1)] void SetValue( object input ); [DispId(2)] object Value {get; set;} } [ComVisible(true)] public class Thing: IThing { internal object PValue; public void SetValue(object input) { PValue = input; } public object Value { get { return PValue; } set { PValue = (object)value; } } } }
谁能在VB6中解释以下行为?
Dim oThing as Thing Dim input as Variant, output as Variant input = "Some text" Set oThing = new Thing oThing.SetValue(input) ' works fine output = oThing.Value ' works fine Set oThing.Value = input ' fails with runtime error '424': Object required
[new]我将程序集设置为COM可见,并检查标记为"注册COM互操作"的项目属性框("构建"选项卡).
正如您可能猜到的,该示例是我正在使用的实际类的简化版本.我比较了实际类和Thing类(下面)生成的TLB信息.标记为**的行可以在Thing类中找到,但不是实际的类(实际的coclass包含[default] dispinterface IThing),这个额外生成的接口_Thing似乎以两种方式改变了VBA中的行为:(1)属性将不再自动完成,(2)直接赋值给Value现在可以像贡献者找到的那样工作.有什么想法吗?
// Generated .IDL file (by the OLE/COM Object Viewer) // // typelib filename: ThingLib.tlb [ uuid(92093AA7-870E-498A-8B80-97545D221E24), version(1.0), helpstring("AAA Testing COM interop") ] library ThingLib { // TLib : // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D} importlib("mscorlib.tlb"); // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} importlib("stdole2.tlb"); // Forward declare all types defined in this typelib dispinterface IThing; ** interface _Thing; [ uuid(7FC255DD-F82F-4B39-8755-9680A97033B5), version(1.0), custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "ComTest.IThing") ] dispinterface IThing { properties: methods: [id(0x00000001)] void SetValue([in] VARIANT input); [id(0x00000002), propget] VARIANT Value(); [id(0x00000002), propputref] void Value([in] VARIANT rhs); }; [ uuid(D96FB9C7-A0AF-35D3-A0F6-A07A9ED47984), version(1.0), custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "ComTest.Thing") ] coclass Thing { ** [default] interface _Thing; interface _Object; dispinterface IThing; }; ** [ ** odl, ** uuid(C309BDD0-239F-38AA-A057-254F8E01BD4B), ** hidden, ** dual, ** oleautomation, ** custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "ComTest.Thing") ** ] ** interface _Thing : IDispatch { ** }; };
Kris Erickso.. 5
将您的代码更改为:
Dim oThing as Thing Dim input as Variant, output as Variant input = "Some text" Set oThing = new Thing oThing.SetValue(input) ' works fine output = oThing.Value ' works fine Set oThing.Value = input ' Change this line
一切都应该有效.(你必须在VB6中设置对象,你试图让一个对象,这只能用于原子类型).
将您的代码更改为:
Dim oThing as Thing Dim input as Variant, output as Variant input = "Some text" Set oThing = new Thing oThing.SetValue(input) ' works fine output = oThing.Value ' works fine Set oThing.Value = input ' Change this line
一切都应该有效.(你必须在VB6中设置对象,你试图让一个对象,这只能用于原子类型).