How to cast a latebound object to a specific interface in VB6?


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: How to cast a latebound object to a specific interface in VB6?

  1. #1
    Kurt Sune Guest

    How to cast a latebound object to a specific interface in VB6?

    Howdy,
    I am wondering if it is possible to cast a latebound object to a latebound
    interface????

    Example:

    I can do earlybound on the interface like this:
    Dim i1 As interfacetest.ikomponent1
    Dim i2 As interfacetest.ikomponent2
    Dim o As Object
    Dim o2 As Object

    'New, typed interface
    Set o = New interfacetest.ckomponent
    Set i2 = o 'VB does an implicit conversion
    b = i2.FuncEtt(s)

    Result: The FuncEtt method of .ikomponent2 gets executed.


    However I find no way of achieving this with latebound interface:

    Dim i1 As interfacetest.ikomponent1
    Dim i2 As interfacetest.ikomponent2
    Dim o As Object
    Dim o2 As Object

    'CreateObject, nontyped interface
    Set o = CreateObject("interfacetest.ckomponent")
    Set o2 = CreateObject("interfacetest.ikomponent2")
    Set o2 = o 'VB sets the pointer to the original komponent
    b = o2.FuncEtt(s)

    Result: The FuncEtt method of .ckomponent gets executed.


    I fwould like to do this:
    Dim o As Object
    Dim o2 As Object

    Set o = CreateObject("interfacetest.ckomponent")
    Set o2 = CreateObject("interfacetest.ikomponent2")
    Set o2 = CAST (o as o2)
    b = o2.FuncEtt(s)

    And the effect would be:
    The FuncEtt method of .ikomponent2 gets executed.







  2. #2
    willy Van den Driessche Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    AFAIK, late bound means primary interface by definition. The only way i know
    of to get at an alternate interface, is to have a wrapper class that exposes
    the methods you want to call through its primary interface. You pass the
    wrapper the object on which you want to access a secundary interface and
    access these methods via the wrapper object.

    Hope this helps.

    "Kurt Sune" <michal.rr@home.se> wrote:
    >Howdy,
    >I am wondering if it is possible to cast a latebound object to a latebound
    >interface????
    >
    >Example:
    >
    >I can do earlybound on the interface like this:
    >Dim i1 As interfacetest.ikomponent1
    >Dim i2 As interfacetest.ikomponent2
    >Dim o As Object
    >Dim o2 As Object
    >
    >'New, typed interface
    > Set o = New interfacetest.ckomponent
    > Set i2 = o 'VB does an implicit conversion
    > b = i2.FuncEtt(s)
    >
    >Result: The FuncEtt method of .ikomponent2 gets executed.
    >
    >
    >However I find no way of achieving this with latebound interface:
    >
    >Dim i1 As interfacetest.ikomponent1
    >Dim i2 As interfacetest.ikomponent2
    >Dim o As Object
    >Dim o2 As Object
    >
    >'CreateObject, nontyped interface
    > Set o = CreateObject("interfacetest.ckomponent")
    > Set o2 = CreateObject("interfacetest.ikomponent2")
    > Set o2 = o 'VB sets the pointer to the original komponent
    > b = o2.FuncEtt(s)
    >
    >Result: The FuncEtt method of .ckomponent gets executed.
    >
    >
    >I fwould like to do this:
    >Dim o As Object
    >Dim o2 As Object
    >
    > Set o = CreateObject("interfacetest.ckomponent")
    > Set o2 = CreateObject("interfacetest.ikomponent2")
    > Set o2 = CAST (o as o2)
    > b = o2.FuncEtt(s)
    >
    >And the effect would be:
    >The FuncEtt method of .ikomponent2 gets executed.
    >
    >
    >
    >
    >
    >



  3. #3
    James Barbetti Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    Hi Willy, Kurt

    >Willy said:
    >AFAIK, late bound means primary interface by definition. The only way
    >i know of to get at an alternate interface, is to have a wrapper
    >class that exposes the methods you want to call through its primary >interface.


    >You pass the wrapper the object on which you want to access a
    >secondary interface and access these methods via the wrapper object.


    That works.

    Another very naughty alternative - if you're writing the implementation classes
    - is to declare the methods and properties of the interface implementation
    Public rather than Private. That way you can get at all the interface-specific
    stuff via the class's default interface. Though, frankly, going

    For i = 1 To X.IAnyOldInterface_Count ...

    is a right dog, there is a benefit: you can actually *get* at the non-default
    interfaces from "type-challenged" scripting languages like VBScript and ASP.
    I vaguely recall using this approach once - I had to get some interface-happy
    type libraries working properly from ASP, back in about 1999.

    >Kurt asked:
    >>Howdy, I am wondering if it is possible to cast a latebound object
    >>to a latebound interface????


    Not really. But you can fake it. Two different ways. The way I suggest
    is hideous (so hideous I haven't used it in more than two years) but it requires
    less coding, slightly lower overhead, and would work in a scripting language.

    >>I fwould like to do this:
    >>Dim o As Object
    >>Dim o2 As Object
    >> Set o = CreateObject("interfacetest.ckomponent")
    >> Set o2 = CreateObject("interfacetest.ikomponent2")
    >> Set o2 = CAST (o as o2) '<-- wouldn't be enough?!
    >> b = o2.FuncEtt(s)
    >>And the effect would be:
    >>The FuncEtt method of .ikomponent2 gets executed.


    That might actually be borderline possible, though I haven't seen it done.
    You'd need a syntax something like this:

    Set O2 = CastObjectAs(o, o2)

    ...and the implementation would have to find an interface of o that implemented
    all of the methods and properties of o2 (problem: what if there is more than
    one!?), and then fake a new object with a vtable (a table of pointers to
    the implementations of methods and properties) on the fly. It'd take some
    rocket science though (on the fly machine-code generation. Horrible!).

    Hope this helps,
    James

  4. #4
    Michael Culley Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    > Another very naughty alternative - if you're writing the implementation
    classes
    > - is to declare the methods and properties of the interface implementation
    > Public rather than Private. That way you can get at all the

    interface-specific
    > stuff via the class's default interface. Though, frankly, going
    >
    > For i = 1 To X.IAnyOldInterface_Count ...


    You could also define a second function that is public that calls
    IAnyOldInterface_Count.

    --
    Michael Culley
    www.vbdotcom.com



  5. #5
    Joe \Nuke Me Xemu\ Foster Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    "James Barbetti" <james_barbetti@yahoo.com> wrote in message <news:3d0a7e2c$1@10.1.10.29>...

    > >Willy said:
    > >AFAIK, late bound means primary interface by definition. The only way
    > >i know of to get at an alternate interface, is to have a wrapper
    > >class that exposes the methods you want to call through its primary >interface.

    >
    > >You pass the wrapper the object on which you want to access a
    > >secondary interface and access these methods via the wrapper object.

    >
    > That works.


    It's also similar to what you have to do to get events and polymorphism
    into spitting distance of each other.

    > >Kurt asked:
    > >>Howdy, I am wondering if it is possible to cast a latebound object
    > >>to a latebound interface????

    >
    > Not really. But you can fake it. Two different ways. The way I suggest
    > is hideous (so hideous I haven't used it in more than two years) but it requires
    > less coding, slightly lower overhead, and would work in a scripting language.


    I wonder if COMMUNE could provide a way to make this easy, without Rob's
    having another hissy-fit over "overhead" that doesn't actually exist...

    --
    Joe Foster <mailto:jlfoster%40znet.com> Space Cooties! <http://www.xenu.net/>
    WARNING: I cannot be held responsible for the above They're coming to
    because my cats have apparently learned to type. take me away, ha ha!



  6. #6
    Kurt Sune Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    "James Barbetti" <james_barbetti@yahoo.com> wrote in message
    news:3d0a7e2c$1@10.1.10.29...
    >
    > Hi Willy, Kurt
    >
    > >Willy said:
    > >AFAIK, late bound means primary interface by definition. The only way
    > >i know of to get at an alternate interface, is to have a wrapper
    > >class that exposes the methods you want to call through its primary

    >interface.
    >
    > >You pass the wrapper the object on which you want to access a
    > >secondary interface and access these methods via the wrapper object.

    >
    > That works.
    >
    > Another very naughty alternative - if you're writing the implementation

    classes
    > - is to declare the methods and properties of the interface implementation
    > Public rather than Private. That way you can get at all the

    interface-specific
    > stuff via the class's default interface. Though, frankly, going
    >
    > For i = 1 To X.IAnyOldInterface_Count ...
    >
    > is a right dog, there is a benefit: you can actually *get* at the

    non-default
    > interfaces from "type-challenged" scripting languages like VBScript and

    ASP.
    > I vaguely recall using this approach once - I had to get some

    interface-happy
    > type libraries working properly from ASP, back in about 1999.
    >
    > >Kurt asked:
    > >>Howdy, I am wondering if it is possible to cast a latebound object
    > >>to a latebound interface????

    >
    > Not really. But you can fake it. Two different ways. The way I suggest
    > is hideous (so hideous I haven't used it in more than two years) but it

    requires
    > less coding, slightly lower overhead, and would work in a scripting

    language.
    >
    > >>I fwould like to do this:
    > >>Dim o As Object
    > >>Dim o2 As Object
    > >> Set o = CreateObject("interfacetest.ckomponent")
    > >> Set o2 = CreateObject("interfacetest.ikomponent2")
    > >> Set o2 = CAST (o as o2) '<-- wouldn't be enough?!
    > >> b = o2.FuncEtt(s)
    > >>And the effect would be:
    > >>The FuncEtt method of .ikomponent2 gets executed.

    >
    > That might actually be borderline possible, though I haven't seen it done.
    > You'd need a syntax something like this:
    >
    > Set O2 = CastObjectAs(o, o2)
    >
    > ..and the implementation would have to find an interface of o that

    implemented
    > all of the methods and properties of o2 (problem: what if there is more

    than
    > one!?), and then fake a new object with a vtable (a table of pointers to
    > the implementations of methods and properties) on the fly. It'd take some
    > rocket science though (on the fly machine-code generation. Horrible!).
    >
    > Hope this helps,
    > James




  7. #7
    Kurt Sune Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    Thanks for answer.

    I dont quite understand your hideous solution.
    Could you elaborate a bit, please?


    /k



    "James Barbetti" <james_barbetti@yahoo.com> wrote in message
    news:3d0a7e2c$1@10.1.10.29...
    >
    > Hi Willy, Kurt
    >
    > >Willy said:
    > >AFAIK, late bound means primary interface by definition. The only way
    > >i know of to get at an alternate interface, is to have a wrapper
    > >class that exposes the methods you want to call through its primary

    >interface.
    >
    > >You pass the wrapper the object on which you want to access a
    > >secondary interface and access these methods via the wrapper object.

    >
    > That works.
    >
    > Another very naughty alternative - if you're writing the implementation

    classes
    > - is to declare the methods and properties of the interface implementation
    > Public rather than Private. That way you can get at all the

    interface-specific
    > stuff via the class's default interface. Though, frankly, going
    >
    > For i = 1 To X.IAnyOldInterface_Count ...
    >
    > is a right dog, there is a benefit: you can actually *get* at the

    non-default
    > interfaces from "type-challenged" scripting languages like VBScript and

    ASP.
    > I vaguely recall using this approach once - I had to get some

    interface-happy
    > type libraries working properly from ASP, back in about 1999.
    >
    > >Kurt asked:
    > >>Howdy, I am wondering if it is possible to cast a latebound object
    > >>to a latebound interface????

    >
    > Not really. But you can fake it. Two different ways. The way I suggest
    > is hideous (so hideous I haven't used it in more than two years) but it

    requires
    > less coding, slightly lower overhead, and would work in a scripting

    language.
    >
    > >>I fwould like to do this:
    > >>Dim o As Object
    > >>Dim o2 As Object
    > >> Set o = CreateObject("interfacetest.ckomponent")
    > >> Set o2 = CreateObject("interfacetest.ikomponent2")
    > >> Set o2 = CAST (o as o2) '<-- wouldn't be enough?!
    > >> b = o2.FuncEtt(s)
    > >>And the effect would be:
    > >>The FuncEtt method of .ikomponent2 gets executed.

    >
    > That might actually be borderline possible, though I haven't seen it done.
    > You'd need a syntax something like this:
    >
    > Set O2 = CastObjectAs(o, o2)
    >
    > ..and the implementation would have to find an interface of o that

    implemented
    > all of the methods and properties of o2 (problem: what if there is more

    than
    > one!?), and then fake a new object with a vtable (a table of pointers to
    > the implementations of methods and properties) on the fly. It'd take some
    > rocket science though (on the fly machine-code generation. Horrible!).
    >
    > Hope this helps,
    > James




  8. #8
    James Barbetti Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    Hi Kurt

    >Thanks for the answer.
    >I dont quite understand your hideous solution.
    >Could you elaborate a bit, please?


    Say you have an interface (IFace) with one property (say, Name) and two classes
    that implement it (Imp1 and Imp2). Imp1 and Imp2 both have an "Implements
    IFace" line. Instead of declaring

    Private Property Get IFace_Name() As String
    '... etc...
    End Property

    in each class, you declare

    PUBLIC Property Get IFace_Name() As String
    '... etc...
    End Property

    then you don't need any latebound casting. Because both imp1 and imp2 declare
    a public IFace_Name property, you can use polymorphism to reference them
    both late-bound.

    '
    'Late-bound
    '
    Dim imp1Or2 As Object
    If Rnd()<.5 Then
    Set imp1Or2 = CreateObject("impLibrary.imp1")
    Else
    Set imp1Or2 = CreateObject("impLibrary.imp1")
    End If
    Debug.Print imp1Or2.IFace_Name

    '
    '...or Early-bound...
    '
    Dim earlyBoundImp As IFace
    Set earlyBoundImp = imp1Or2
    Debug.Print earlyBoundImp.Name


    ...
    The problem is that the default interface of your implementation class gets
    rather cluttered. Oh, and it's ugly.
    Hope that clears it up.
    Seeya,
    James


  9. #9
    Burton Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    I vaguely remember a teacher once mentioning that you must duplicate the interface
    for late-bound languages like vbscript.

    one solution might be to copy and paste the interface definition into the
    implementing class and delegate to the private interface methods that the
    ide creates for the actual interface implementation

    i.e.:
    *** IInterface.cls
    public sub Method1(Arg1 as string)
    end sub

    *** Implementor.cls
    Implements IInterface

    private sub IInterface_Method1(Arg1 as string)
    ' Actual implementation code
    end sub

    ' use this to access late-bound
    public sub Method1(Arg1 as string)
    IInterface_Method1 Arg1
    end sub

    Or you make some sort of macro that produces the same effect, maybe a vb
    add-in/wizard that senses that you've added the implements keyword and automatically
    looks up the interface definition and creates the delegation code.


    "Kurt Sune" <michal.rr@home.se> wrote:
    >Howdy,
    >I am wondering if it is possible to cast a latebound object to a latebound
    >interface????
    >
    >Example:
    >
    >I can do earlybound on the interface like this:
    >Dim i1 As interfacetest.ikomponent1
    >Dim i2 As interfacetest.ikomponent2
    >Dim o As Object
    >Dim o2 As Object
    >
    >'New, typed interface
    > Set o = New interfacetest.ckomponent
    > Set i2 = o 'VB does an implicit conversion
    > b = i2.FuncEtt(s)
    >
    >Result: The FuncEtt method of .ikomponent2 gets executed.
    >
    >
    >However I find no way of achieving this with latebound interface:
    >
    >Dim i1 As interfacetest.ikomponent1
    >Dim i2 As interfacetest.ikomponent2
    >Dim o As Object
    >Dim o2 As Object
    >
    >'CreateObject, nontyped interface
    > Set o = CreateObject("interfacetest.ckomponent")
    > Set o2 = CreateObject("interfacetest.ikomponent2")
    > Set o2 = o 'VB sets the pointer to the original komponent
    > b = o2.FuncEtt(s)
    >
    >Result: The FuncEtt method of .ckomponent gets executed.
    >
    >
    >I fwould like to do this:
    >Dim o As Object
    >Dim o2 As Object
    >
    > Set o = CreateObject("interfacetest.ckomponent")
    > Set o2 = CreateObject("interfacetest.ikomponent2")
    > Set o2 = CAST (o as o2)
    > b = o2.FuncEtt(s)
    >
    >And the effect would be:
    >The FuncEtt method of .ikomponent2 gets executed.
    >
    >
    >
    >
    >
    >



  10. #10
    Dwayne D Guest

    Re: How to cast a latebound object to a specific interface in VB6?


    The reason you can't access the Interface the way you're coding it is because
    it the interface is not part of the Default Interface (which is an IDispatch
    Interface....which only exposes the Default Interface...the Public members
    ONLY).

    So...here is one "clean & simple" solution to your problem.

    Instead of changing all of the interface memebers from Private to Public,
    just declare a single Public Property that exposes the Interface you want
    to access via the object.

    Example Interface Definition for IPerson
    =============================
    Public Property Get Name() As String
    'NO CODE HERE BECAUSE THIS IS ONLY AN INTERFACE DEFINITION
    End Property

    Public Property Let Name(ByVal NewName As String)
    'NO CODE HERE BECAUSE THIS IS ONLY AN INTERFACE DEFINITION
    End Property
    =============================

    Example Concrete Class Definition for the "SomeServer.SomeClass" Class
    =============================
    Implements IPerson

    Private mstrName as String

    Private Property Get IPerson_Name() As String
    IPerson_Name = mstrName
    End Property

    Private Property Let IPerson_Name(ByVal RHS As String)
    mstrName = RHS
    End Property

    Public Property Get IPerson() As IPerson
    Set IPerson = Me
    End Property
    =============================


    Example Calling Code
    =============================
    Dim oDude As Object

    Set oDude = CreateObject("SomeServer.SomeClass")
    oDude.IPerson.Name = "Dude"
    MsgBox oDude.IPerson.Name
    =============================


    My example doesn't quite follow your problem but you should be able to apply
    it. All you needed to add is one "Public Property Get" routine to expose
    the interface in question. No messy looking memeber signatures and no cluttering
    up your public interface.

    Hope this helps!!!

    Dwayne D

  11. #11
    Kurt Sune Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    Thank you,
    now I see the (hideous) light.


    "James Barbetti" <james_barbetti@yahoo.com> wrote in message
    news:3d104a60$1@10.1.10.29...
    >
    > Hi Kurt
    >
    > >Thanks for the answer.
    > >I dont quite understand your hideous solution.
    > >Could you elaborate a bit, please?

    >
    > Say you have an interface (IFace) with one property (say, Name) and two

    classes
    > that implement it (Imp1 and Imp2). Imp1 and Imp2 both have an "Implements
    > IFace" line. Instead of declaring
    >
    > Private Property Get IFace_Name() As String
    > '... etc...
    > End Property
    >
    > in each class, you declare
    >
    > PUBLIC Property Get IFace_Name() As String
    > '... etc...
    > End Property
    >
    > then you don't need any latebound casting. Because both imp1 and imp2

    declare
    > a public IFace_Name property, you can use polymorphism to reference them
    > both late-bound.
    >
    > '
    > 'Late-bound
    > '
    > Dim imp1Or2 As Object
    > If Rnd()<.5 Then
    > Set imp1Or2 = CreateObject("impLibrary.imp1")
    > Else
    > Set imp1Or2 = CreateObject("impLibrary.imp1")
    > End If
    > Debug.Print imp1Or2.IFace_Name
    >
    > '
    > '...or Early-bound...
    > '
    > Dim earlyBoundImp As IFace
    > Set earlyBoundImp = imp1Or2
    > Debug.Print earlyBoundImp.Name
    >
    >
    > ..
    > The problem is that the default interface of your implementation class

    gets
    > rather cluttered. Oh, and it's ugly.
    > Hope that clears it up.
    > Seeya,
    > James
    >




  12. #12
    Kurt Sune Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    Yes it did help.

    I had to change this though:

    Public Property Get IIPerson() As IPerson
    Set IIPerson = Me
    End Property

    otherwise I got Ambigious name detected.

    /k

    "Dwayne D" <vb.@127.0.0.1> wrote in message news:3d110462$1@10.1.10.29...
    >
    > The reason you can't access the Interface the way you're coding it is

    because
    > it the interface is not part of the Default Interface (which is an

    IDispatch
    > Interface....which only exposes the Default Interface...the Public members
    > ONLY).
    >
    > So...here is one "clean & simple" solution to your problem.
    >
    > Instead of changing all of the interface memebers from Private to Public,
    > just declare a single Public Property that exposes the Interface you want
    > to access via the object.
    >
    > Example Interface Definition for IPerson
    > =============================
    > Public Property Get Name() As String
    > 'NO CODE HERE BECAUSE THIS IS ONLY AN INTERFACE DEFINITION
    > End Property
    >
    > Public Property Let Name(ByVal NewName As String)
    > 'NO CODE HERE BECAUSE THIS IS ONLY AN INTERFACE DEFINITION
    > End Property
    > =============================
    >
    > Example Concrete Class Definition for the "SomeServer.SomeClass" Class
    > =============================
    > Implements IPerson
    >
    > Private mstrName as String
    >
    > Private Property Get IPerson_Name() As String
    > IPerson_Name = mstrName
    > End Property
    >
    > Private Property Let IPerson_Name(ByVal RHS As String)
    > mstrName = RHS
    > End Property
    >
    > Public Property Get IPerson() As IPerson
    > Set IPerson = Me
    > End Property
    > =============================
    >
    >
    > Example Calling Code
    > =============================
    > Dim oDude As Object
    >
    > Set oDude = CreateObject("SomeServer.SomeClass")
    > oDude.IPerson.Name = "Dude"
    > MsgBox oDude.IPerson.Name
    > =============================
    >
    >
    > My example doesn't quite follow your problem but you should be able to

    apply
    > it. All you needed to add is one "Public Property Get" routine to expose
    > the interface in question. No messy looking memeber signatures and no

    cluttering
    > up your public interface.
    >
    > Hope this helps!!!
    >
    > Dwayne D




  13. #13
    Anthony Jones Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    Kurt,

    Whilst this works in most circumstances you should be aware that the
    behaviour seen is not entirely COM compliant. Specifically this technique
    fails if the calls are being marshalled via a proxy-stub.

    If you never expect the object to be called in this way across a thread
    boundary then you should be OK with it.

    --
    Anthony Jones
    Nuesoft Ltd



  14. #14
    Kurt Sune Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    You're right. Tried it in MTS. Doesnt work.

    Do you think I am bound to the hideous way James Barbetti suggested?

    /k

    "Anthony Jones" <anthony.jones@nonuesoft.spamco.uk> wrote in message
    news:3d119120@10.1.10.29...
    > Kurt,
    >
    > Whilst this works in most circumstances you should be aware that the
    > behaviour seen is not entirely COM compliant. Specifically this technique
    > fails if the calls are being marshalled via a proxy-stub.
    >
    > If you never expect the object to be called in this way across a thread
    > boundary then you should be OK with it.
    >
    > --
    > Anthony Jones
    > Nuesoft Ltd
    >
    >




  15. #15
    Anthony Jones Guest

    Re: How to cast a latebound object to a specific interface in VB6?

    >Do you think I am bound to the hideous way James Barbetti suggested?

    No. In the scenario of using an MTS object from a Scripting language I would
    prefer to use the Wrapper object approach as Willy originally suggested.

    --
    Anthony Jones
    Nuesoft Ltd



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center