Board index » delphi » Interface typecasting question

Interface typecasting question

Ok, lets say I have an interface called IMyInterface and an object called
TMyObject declared as such (as an automation object)

TMyObject = class(TIntefacedObject, IMyInterface)

Now, in my code say I do the following (assume these two functions reside in
the same application, say in another automation object):

function SomeFunction: IMyInteface;
var
  moSomeObject: TMyObject;

begin
  moSomeObject := TMyObject.Create;
  moSomeObject.SomeObjectInternal;

  Result := moSomeObject;
  Result.SomeInterfaceFunction;
end;

procedure SomeOtherFunction;
var
  miSomeObject: IMyInterface;
  moSameObject: TMyObject;

begin
  miSomeObject := SomeFunction;
  miSomeObject.SomeOtherInterfaceFunction;

  moSameObject := miSomeObject;
end;

So, is there any to make moSameObject contain a valid pointer to the
underlying TMyObject?  I would like to use this to call 'internal'
fiunctions that I don't want the DCOM client being able to call.  Other than
doing the typecasting, how would I have functions that are for internal (to
the DCOM server) use only?  Maybe have two type libraries, one with the
'external' interfaces and one with the 'internal' and then not publish the
internal?

TIA,
Michael Trainor

 

Re:Interface typecasting question


You should avoid trying to use the underlying object.

A better way is to have your object support some other interface
IMySpecialbackdoor, and use QueryInterface on your IMyInterface
instance to get to the interface that you know about but choose not to
document.

Regards
Mark Smith

Re:Interface typecasting question


Ok, thanks, that's the type of tip I was looking for.
Quote
> You should avoid trying to use the underlying object.

> A better way is to have your object support some other interface
> IMySpecialbackdoor, and use QueryInterface on your IMyInterface
> instance to get to the interface that you know about but choose not to
> document.

Re:Interface typecasting question


Michael,

Quote
> Ok, lets say I have an interface called IMyInterface and an object called
> TMyObject declared as such (as an automation object)

> TMyObject = class(TIntefacedObject, IMyInterface)

> Now, in my code say I do the following (assume these two functions reside in
> the same application, say in another automation object):

> function SomeFunction: IMyInteface;
> var
>   moSomeObject: TMyObject;

> begin
>   moSomeObject := TMyObject.Create;
>   moSomeObject.SomeObjectInternal;

>   Result := moSomeObject;
>   Result.SomeInterfaceFunction;
> end;

Be very careful when you're mixing object model (TMyObject) and
interface model (IMyInterface). It can get very messy... So consider
declaring another interface in the TMyObject class declaration that is a
helper interface that can access those in "SomeObjectInternal" methods.
I'm assuming that these methods are not declared and not accessible
through the IMyInterface. This way all you have to do is something like:

IMyInternalHelpers = interface
  procedure SomeObjectInternal;
  procedure SomeOtherStuff;
end;

TMyObject = class(TIntefacedObject, IMyInterface, IMyInternalHelpers)
...
end;

It makes for a tad bit of repetition, but it ensures when using the
interface model you stick with it and when using the object model you
only stick to objects. Another option is to delegate those
"SomeObjectInternal" methods to another class and use implements keyword
to delegate the implementation.

So you could implement

function SomeFunction: IMyInteface;
begin
  Result := TMyObject.Create;
  if Assigned(Result) then
  begin
    // Call that internal interface method
    // You could also do a QI to be extra safe, but
    // let's assume you know Result supports IMyInternalHelpers
    (Result as IMyInternalHelpers).SomeObjectInternal;

    Result.SomeInterfaceFunction;
  end;
end;

No need to worry about what object frees what and mixing models. Best
bet is to pick a model and stick to it. What can I say, I'm basised
toward interfaces. :)

HTH,

Robert

Other Threads