2009-03-21 13 views
1

die folgende C# Klasse Gegeben:VB6 zu C# Interop: Kann nicht direkt eine Eigenschaft vom Typ 'Objekt' gesetzt

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; 
      } 
     } 

    } 
} 

Kann jemand das folgende Verhalten in VB6 erklären?

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 

[neu] stelle ich die Montage COM-sichtbar und überprüft die Projekteigenschaften Feld "Register für COM-Interop" (Build Registerkarte) zu sein.

Wie Sie sich denken können, ist das Beispiel eine reduzierte minimale Version der tatsächlichen Klasse, die ich verwende. Ich habe die generierten TLB-Informationen für die tatsächliche Klasse und die Thing-Klasse (unten) verglichen. Die mit ** markierten Zeilen befinden sich in der Thing-Klasse, aber nicht in der eigentlichen Klasse (die aktuelle Coclass enthält [default] dispinterface IThing) und diese extra generierte Schnittstelle _Thing ändert das Verhalten in VBA auf zwei Arten: (1) Die Eigenschaften werden nicht mehr AutoComplete, (2) die direkte Zuweisung zu Value funktioniert jetzt, wie die Mitwirkenden gefunden haben. Irgendwelche Gedanken?

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

Antwort

1

Jeremy, habe ich versucht, den Code und es funktioniert gut (obwohl ich Excel VBA verwendet, da ich habe VB6 nicht installiert ist). Es ist ein Tippfehler in Ihrem Code, wo

object Value (get; set;) 

object Value {get; set;} 

sein soll, aber ich bezweifle, dass es etwas mit Ihrem Fehler zu tun hat, da es Ihnen einen Compiler-Fehler geben soll. Hast du den Code genau wie hier beschrieben?

0

Ich habe auch Ihre COM-Interface-Implementierung mit einem VB6-Client ohne Probleme versucht (mit Ausnahme des Tippfehlers Jakob in der Value Eigenschaft erwähnt).

5

Ihren Code ändern:

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 

Und sollte alles funktionieren. (Sie müssen Objekte in VB6 setzen, Sie versuchen Lassen Sie ein Objekt, das nur für atomare Typen getan werden kann).

+0

Sie haben Recht, dass der Code, den ich gab, funktioniert (wenn Tippfehler korrigiert), aber die ursprüngliche Klasse, von der ich es kopiert habe, funktioniert immer noch nicht. Sehen Sie meine bearbeitete Frage für COM (TLB) Informationsunterschiede zwischen dem ursprünglichen und dem Kürzungsbeispiel - ich kann nicht herausfinden, was den Unterschied verursacht hat. –