I am learning about COM and Interfaces and have following experimental code:
type
IA = interface(IInterface)
['{C9C5C992-3F67-48C5-B215-7DCE6A61F0E8}']
end;
IB = interface(IA)
['{F1799437-AD12-471B-8716-F1D93D1692FC}']
end;
IC = interface(IB)
['{01780E8C-C47D-468E-8E42-4BFF3F495D51}']
end;
TBO = class(TInterfacedObject, IB)
end;
procedure TForm1.FormCreate(Sender: TObject);
var
x: TBO;
a: IInterface;
begin
x := TBO.Create;
IInterface(x)._AddRef;
if Assigned(TBO.GetInterfaceEntry(IA)) then memo1.lines.add('GetInterfaceEntry IA: OK'); // Why not?
if Assigned(TBO.GetInterfaceEntry(IB)) then memo1.lines.add('GetInterfaceEntry IB: OK');
if Assigned(TBO.GetInterfaceEntry(IC)) then memo1.lines.add('GetInterfaceEntry IC: OK');
if x.QueryInterface(IA, a)=S_OK then memo1.lines.add('QueryInterface TA: OK'); // Why not?
if x.QueryInterface(IB, a)=S_OK then memo1.lines.add('QueryInterface TB: OK');
if x.QueryInterface(IC, a)=S_OK then memo1.lines.add('QueryInterface TC: OK');
if Supports(TBO, IA) then memo1.lines.add('Supports TA: OK'); // Why not?
if Supports(TBO, IB) then memo1.lines.add('Supports TB: OK');
if Supports(TBO, IC) then memo1.lines.add('Supports TC: OK');
if Supports(x, IA, a) then memo1.lines.add('Supports(2) TA: OK'); // Why not?
if Supports(x, IB, a) then memo1.lines.add('Supports(2) TB: OK');
if Supports(x, IC, a) then memo1.lines.add('Supports(2) TC: OK');
end;
Output:
GetInterfaceEntry IB: OK
QueryInterface TB: OK
Supports TB: OK
Supports(2) TB: OK
But I need:
GetInterfaceEntry IA: OK
GetInterfaceEntry IB: OK
QueryInterface TA: OK
QueryInterface TB: OK
Supports TA: OK
Supports TB: OK
Supports(2) TA: OK
Supports(2) TB: OK
I understand that IB
is a superset of IA
due to the Interface inheritance. In my understanding, since TBO
implements IB
, it automatically implements IA
. But why does Supports()
, QueryInterface()
, GetInterfaceEntry()
return false?
How do I query if TBO
implements IA
directly OR indirectly, i.e. by implementing a superset of IA
? I need both, a static class function like GetInterfaceEntry
and a dynamic object reference variant like QueryInterface
.
To declare a class that implements an interface, you include an implements clause in the class declaration. Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class.
isInterface() method The isArray() method of the Class class is used to check whether a class is an interface or not. This method returns true if the given class is an interface. Otherwise, the method returns false , indicating that the given class is not an interface.
With the aim to make the code robust, i would like to check that the class implements the interface before instantiation / casting. I would like the the keyword 'instanceof' to verify a class implements an interface, as i understand it, it only verifies class type.
8. Is it OK if a class definition implements two interfaces, each of which has the same definition for the constant PI? a. No---if a class implements several interfaces, each constant must be defined in only one interface.
This is a known quirk of Delphi. Even though IB
inherits from IA
, TBO
must explicitly specify both IA
and IB
in order for Supports()
to retrieve both interfaces.
TBO = class(TInterfacedObject, IA, IB)
I forget the technical reason for this. Something to do with a limitation in how the compiler generates the interface table for TBO
. It does not automatically include inherited interfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With