【发布时间】:2014-09-02 12:16:59
【问题描述】:
我正在学习 COM 和接口,并有以下实验代码:
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;
输出:
GetInterfaceEntry IB: OK
QueryInterface TB: OK
Supports TB: OK
Supports(2) TB: OK
但我需要:
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
由于接口继承,我了解IB 是IA 的超集。据我了解,由于TBO实现了IB,它自动实现了IA。但是为什么Supports()、QueryInterface()、GetInterfaceEntry()返回false?
如何查询TBO 是否直接或间接实现IA,即通过实现IA 的超集?我需要两个,一个像GetInterfaceEntry 这样的静态类函数和一个像QueryInterface 这样的动态对象引用变体。
【问题讨论】:
-
考虑
IA = interface、IA1 = interface(IA)和IA2 = interface(IA)。现在TAggregate = class(TInterfacedObject, IA1, IA2)IA1 和IA2 都被委托:property ImplIA1: IA1 read FIA1 implements IA1;和property ImplIA2: IA2 read FIA2 implements IA2;现在,如果您询问TAggregate的实例以获取其IA接口,它应该返回哪个实现?关键是接口“继承”并不是真正的继承。所以这个对象不会实现一个“祖先”接口,除非它明确地这样做。 -
@CraigYoung 对此进行扩展的答案会很有用。
-
@CraigYoung 非常感谢这个例子。理解为什么需要显式命名非常有帮助。