OO Class Parameters? 
Author Message
 OO Class Parameters?

I've just started with the new version of Stony Brook M2 and am very
impressed with
the added value of the upgrade.

My first project (perhaps overreaching) for using the ISO OO extensions
to M2 is to build
an M2 interface to a third party COM package for accessing and
manipulating a e-mailing system.

After some struggle (if you are using Ole2, be careful about VARIANT
parameter - they may be value
and require all 16 bytes be pushed!) I've been able to initialize and
log-on, but have run
into something that puzzles me:

    I've been unable to get the compiler to accept a descendent class
object as parameter when the
    parameter is defined as the ancestor class.

    eg, I have a class defined as

       ABSTRACT CLASS C;
          INHERIT Ole2.IUnknown;
             ...
       END C;

     where the ancestor class is

         ABSTRACT CLASS IUnknown;
           REVEAL QueryInterface, AddRef, Release;
           ABSTRACT PROCEDURE QueryInterface(    iid:       IID;
                                             VAR interface: IUnknown):
HRESULT;
           ABSTRACT PROCEDURE AddRef(): ULONG;
           ABSTRACT PROCEDURE Release(): ULONG;
         END IUnknown;

      I have variables declared as my class C,

      VAR  IGWAccount     :C;
           rootAccount    :C;

      <rootAccount created here ...>

      The compiler will not accept the second parameter below, giving
      an "Incorrect type of actual parameter" error.

         hRes := rootAccount.QueryInterface(IGWAccount.IID, IGWAccount);

I can use a CAST(IUnknown, IGWAccount) to get around this, but I thought
that ancestors
were assignment compatible with their descendents. Is there something I
am overlooking about
the ISO Object Oriented M2 extensions that I should be doing to make
this work?

Thanks for any help,

Tom Breeden



Sat, 18 Jan 2003 03:00:00 GMT  
 OO Class Parameters?
You can assign a child to a parent, but not the other way.

QueryInterface has a VAR parameter of IUnknown. This means that something
inside the procedure is assigning to your passed variable which in this case
is a child of IUnknown. This is in essence trying to assign an IUnknown to
your child class C.

This cannot be allowed because an object of IUnknown may not have all the
information of the child class C. Your object variable of type class C
rightly assumes that all information of C and it ancestors is available.
Additional information may or may not be present, which would mean a child
of C can be assigned to your object  variable of type class C.

This slight ugliness is a consequence that COM is objects without "objects"
and is also language independent. We mapped M2 CLASS types to COM objects.
The M2 CLASS types obey M2 assignment rules. COM objects obey COM rules. The
mapping is almost but not quite perfect. Occasionally you might need to use
a CAST, as QueryInterface requires. This is because QueryInterface can and
generally does return a child object even though the parameter type is
always the root COM object, IUnknown.

--
Norman Black
Stony Brook Software
the reply, fubar => ix.netcom


Quote:

> I've just started with the new version of Stony Brook M2 and am very
> impressed with
> the added value of the upgrade.

> My first project (perhaps overreaching) for using the ISO OO extensions
> to M2 is to build
> an M2 interface to a third party COM package for accessing and
> manipulating a e-mailing system.

> After some struggle (if you are using Ole2, be careful about VARIANT
> parameter - they may be value
> and require all 16 bytes be pushed!) I've been able to initialize and
> log-on, but have run
> into something that puzzles me:

>     I've been unable to get the compiler to accept a descendent class
> object as parameter when the
>     parameter is defined as the ancestor class.

>     eg, I have a class defined as

>        ABSTRACT CLASS C;
>           INHERIT Ole2.IUnknown;
>              ...
>        END C;

>      where the ancestor class is

>          ABSTRACT CLASS IUnknown;
>            REVEAL QueryInterface, AddRef, Release;
>            ABSTRACT PROCEDURE QueryInterface(    iid:       IID;
>                                              VAR interface: IUnknown):
> HRESULT;
>            ABSTRACT PROCEDURE AddRef(): ULONG;
>            ABSTRACT PROCEDURE Release(): ULONG;
>          END IUnknown;

>       I have variables declared as my class C,

>       VAR  IGWAccount     :C;
>            rootAccount    :C;

>       <rootAccount created here ...>

>       The compiler will not accept the second parameter below, giving
>       an "Incorrect type of actual parameter" error.

>          hRes := rootAccount.QueryInterface(IGWAccount.IID, IGWAccount);

> I can use a CAST(IUnknown, IGWAccount) to get around this, but I thought
> that ancestors
> were assignment compatible with their descendents. Is there something I
> am overlooking about
> the ISO Object Oriented M2 extensions that I should be doing to make
> this work?

> Thanks for any help,

> Tom Breeden




Sun, 19 Jan 2003 03:00:00 GMT  
 OO Class Parameters?

Ok. Thanks.

Quote:

> You can assign a child to a parent, but not the other way.

> QueryInterface has a VAR parameter of IUnknown. This means that something
> inside the procedure is assigning to your passed variable which in this case
> is a child of IUnknown. This is in essence trying to assign an IUnknown to
> your child class C.

I was thinking of it in reverse.

Here I guess we are just trusting QueryInterface() to return the right
dynamic
type. Maybe you would want to use ISMEMBER() if you are paranoid?

Quote:

> --
> Norman Black
> Stony Brook Software
> the reply, fubar => ix.netcom



> > I've just started with the new version of Stony Brook M2 and am very
> > impressed with
> > the added value of the upgrade.

> >     I've been unable to get the compiler to accept a descendent class
> > object as parameter when the
> >     parameter is defined as the ancestor class.

> >     eg, I have a class defined as

> >        ABSTRACT CLASS C;
> >           INHERIT Ole2.IUnknown;
> >              ...
> >        END C;

> >      where the ancestor class is

> >          ABSTRACT CLASS IUnknown;
> >            REVEAL QueryInterface, AddRef, Release;
> >            ABSTRACT PROCEDURE QueryInterface(    iid:       IID;
> >                                              VAR interface: IUnknown):
> > HRESULT;
> >            ABSTRACT PROCEDURE AddRef(): ULONG;
> >            ABSTRACT PROCEDURE Release(): ULONG;
> >          END IUnknown;

> >       I have variables declared as my class C,

> >       VAR  IGWAccount     :C;
> >            rootAccount    :C;

> >       <rootAccount created here ...>

> >       The compiler will not accept the second parameter below, giving
> >       an "Incorrect type of actual parameter" error.

> >          hRes := rootAccount.QueryInterface(IGWAccount.IID, IGWAccount);



Tue, 21 Jan 2003 03:00:00 GMT  
 OO Class Parameters?
QueryInterface will return the object you request, its the M2 assignment
rules that get in the way with how QueryInterface operates.

--
Norman Black
Stony Brook Software
the reply, fubar => ix.netcom


Quote:

> Ok. Thanks.


> > You can assign a child to a parent, but not the other way.

> > QueryInterface has a VAR parameter of IUnknown. This means that
something
> > inside the procedure is assigning to your passed variable which in this
case
> > is a child of IUnknown. This is in essence trying to assign an IUnknown
to
> > your child class C.

> I was thinking of it in reverse.

> Here I guess we are just trusting QueryInterface() to return the right
> dynamic
> type. Maybe you would want to use ISMEMBER() if you are paranoid?

> > --
> > Norman Black
> > Stony Brook Software
> > the reply, fubar => ix.netcom



> > > I've just started with the new version of Stony Brook M2 and am very
> > > impressed with
> > > the added value of the upgrade.

> > >     I've been unable to get the compiler to accept a descendent class
> > > object as parameter when the
> > >     parameter is defined as the ancestor class.

> > >     eg, I have a class defined as

> > >        ABSTRACT CLASS C;
> > >           INHERIT Ole2.IUnknown;
> > >              ...
> > >        END C;

> > >      where the ancestor class is

> > >          ABSTRACT CLASS IUnknown;
> > >            REVEAL QueryInterface, AddRef, Release;
> > >            ABSTRACT PROCEDURE QueryInterface(    iid:       IID;
> > >                                              VAR interface: IUnknown):
> > > HRESULT;
> > >            ABSTRACT PROCEDURE AddRef(): ULONG;
> > >            ABSTRACT PROCEDURE Release(): ULONG;
> > >          END IUnknown;

> > >       I have variables declared as my class C,

> > >       VAR  IGWAccount     :C;
> > >            rootAccount    :C;

> > >       <rootAccount created here ...>

> > >       The compiler will not accept the second parameter below, giving
> > >       an "Incorrect type of actual parameter" error.

> > >          hRes := rootAccount.QueryInterface(IGWAccount.IID,
IGWAccount);



Tue, 21 Jan 2003 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Access to T'Class vs T'Class as parameter to subprogram

2. class arguments: passing classes as function parameters

3. OO Analysis & Design class

4. OO-REXX: what about these classes ...

5. OO Idiom: Interfaces for derived classes

6. OO Analysis & Design class at KSC

7. File Class In OO COBOL

8. OO Classes - Public Domain Source code

9. The use of the Factory Paragraph versus Class-Object in Object Oriented (OO) COBOL

10. how to extend an instance of visual class: was using RADs in OO way

11. FFI c-struct convenience classes? OO, not with-

12. Simulation Classes in OO Programming

 

 
Powered by phpBB® Forum Software