Com VB6到C互操作:无法直接设置类型为';对象';

Com VB6到C互操作:无法直接设置类型为';对象';,com,vb6,interop,object,Com,Vb6,Interop,Object,考虑到以下C类: 有人能解释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 runti

考虑到以下C类:

有人能解释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
[新] 我将程序集设置为COM可见,并选中标记为“注册COM互操作”(Build选项卡)的项目属性框

正如您可能猜到的,这个示例是我正在使用的实际类的精简版。我比较了为实际类和Thing类生成的TLB信息(如下)。 标记为**的行在Thing类中找到,但在实际的类中找不到(实际的coclass包含[default]dispithing接口),这个额外生成的接口似乎通过两种方式改变了VBA中的行为:(1)属性将不再自动完成,(2)直接赋值现在可以像贡献者发现的那样工作。有什么想法吗

// 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 {
**    };
};

Jeremy,我尝试了你的代码,效果很好(尽管我使用了Excel VBA,因为我没有安装VB6)。你的代码中有一个输入错误

object Value (get; set;)
应该是

object Value {get; set;}

但我怀疑这和你的错误有什么关系,因为它会给你一个编译错误。您是否完全按照您在此处输入的代码进行了尝试?

Jeremy,我尝试了您的代码,效果很好(尽管我使用了Excel VBA,因为我没有安装VB6)。你的代码中有一个输入错误

object Value (get; set;)
应该是

object Value {get; set;}

但我怀疑这和你的错误有什么关系,因为它会给你一个编译错误。您是否完全按照此处所述的方式尝试了代码?

我还使用VB6客户端尝试了COM接口实现,没有出现任何问题(除了
Value
属性中提到的键入Jakob)。

我还使用VB6客户端尝试了COM接口实现,没有出现任何问题(除了
属性中提到的Jakob打字错误)。

将代码更改为:

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中设置对象,您正在尝试
让一个对象,它只能用于原子类型)。

我给出的代码是正确的(当拼写更正时),但我复制它的原始类仍然不工作。请参阅我编辑的COM问题(TLB)原始示例和精简示例之间的信息差异-我无法找出造成差异的原因。你是对的,我给出的代码有效(当拼写更正时),但我复制它的原始类仍然不起作用。请参阅我编辑的COM问题(TLB)原始示例和精简示例之间的信息差异-我无法找出造成差异的原因。