Взаимодействие с VB6 до C #: невозможно напрямую установить свойство типа 'объект' - PullRequest
1 голос
/ 21 марта 2009

Учитывая следующий класс 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

[новый] Я установил сборку так, чтобы она была видимой для COM, и установил флажок в свойствах проекта с надписью «Зарегистрироваться для взаимодействия с COM» (вкладка «Сборка»).

Как вы можете догадаться, пример представляет собой урезанную минимальную версию фактического класса, который я использую. Я сравнил сгенерированную информацию TLB для фактического класса и класса Thing (ниже). Строки, помеченные **, находятся в классе Thing, но не в самом классе (фактический coclass содержит [default] dispinterface IThing), и этот дополнительный сгенерированный интерфейс _Thing, по-видимому, изменяет поведение в VBA двумя способами: свойства больше не будут автозаполняться, (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 {
**    };
};

Ответы [ 3 ]

5 голосов
/ 23 марта 2009

Измените свой код на:

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, вы пытаетесь Пусть объект, что можно сделать только для атомарных типов).

1 голос
/ 21 марта 2009

Джереми, я попробовал ваш код, и он отлично работает (хотя я использовал Excel VBA, так как у меня не установлен VB6). В вашем коде есть опечатка, где

object Value (get; set;)

должно быть

object Value {get; set;}

но я сомневаюсь, что это как-то связано с вашей ошибкой, поскольку она должна дать вам ошибку компиляции. Вы пробовали код в точности так, как вы написали здесь?

0 голосов
/ 22 марта 2009

Я также без проблем попробовал реализацию вашего COM-интерфейса с клиентом VB6 (за исключением опечатки Jakob, упомянутой в свойстве Value).

...