-
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.
-
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.
>
>
>
>
>
>
-
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
-
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
-
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!
-
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
-
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
-
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
-
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.
>
>
>
>
>
>
-
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
-
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
>
-
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
-
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
-
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
>
>
-
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
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|