对于delphi7的接口不能强制转化的问题

今天在发现delphi里的接口是不能强制转化的, 比如如下代码:
ITestInterface  =   interface (IUnknown)
[
' {DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC} ' ]
procedure Chk;
end;

ITestInterface2 
=   interface (IUnknown)
[
' {3B47B113-4664-4CCC-9A69-E378F2D2363E} ' ]
procedure Chk2;
end;

var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt :
=  TTestInterface2.Create;
mInt.Chk;

ITestInterface2(mInt).Chk2;

mInt2 :
=  mInt  as  ITestInterface2;
mInt2.Chk2;
end;


从 运行情况可以看出,在第一种情况 ITestInterface2(mInt).Chk2; 下,实际运行的还是ITestInterface下的procedure Chk;而第二种情况 mInt2 := mInt as ITestInterface2; 就能正确的运行ITestInterface2下的procedure Chk2;了.这是为什么呢?
原来这都出自Delphi的编译之手,在进行强制转化 ITestInterface2(mInt).Chk2; 时, 代码是:
mov eax, [ebp - $ 04 ]
mov edx, [eax]
call dword ptr [edx
+ $0c]

而 进行 mInt.Chk; 调用时的代码也是这个,这说明强制转化时,编译器根本就没有把ITestInterface转化为ITestInterface2,而是理解为直接的对象 强制转化,然后希望能在方法表里找到对应的方法,而且在对接口进行方法的解析时,也只是以方法的声明顺序,而不是实际的方法名来进行解析.所以在Chk为 ITestInterface的第一个方法,而Chk2也为ITestInterface2的第一个方法时,就会直接的调用了 ITestInterface的Chk,而不是ITestInterface2的Chk2.这个结论也可能通过下面这个实验来表明.
ITestInterface  =   interface (IUnknown)
[
' {DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC} ' ]
procedure Chk;
end;

ITestInterface2 
=   interface (IUnknown)
[
' {3B47B113-4664-4CCC-9A69-E378F2D2363E} ' ]
procedure Chk2;
procedure Chk22;
end;

var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt :
=  TTestInterface2.Create;
mInt.Chk;

ITestInterface2(mInt).Chk22;

mInt2 :
=  mInt  as  ITestInterface2;
mInt2.Chk2;
end;

在这种情况下,就会报地址出错,那是因为ITestInterface根本就没有第二个方法.当然下面的代码也能说明问题
ITestInterface  =   interface (IUnknown)
[
' {DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC} ' ]
procedure Chk;
procedure Chk1;
end;

ITestInterface2 
=   interface (IUnknown)
[
' {3B47B113-4664-4CCC-9A69-E378F2D2363E} ' ]
procedure Chk2;
procedure Chk22;
end;

var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt :
=  TTestInterface2.Create;
mInt.Chk;

ITestInterface2(mInt).Chk22;

mInt2 :
=  mInt  as  ITestInterface2;
mInt2.Chk2;
end;

在这种情况下,程序会调用ITestInterface的Chk1方法.

好上面说了强制转化时发生的情况,下面说用as来转化时发生的情况.

当用as来转化时,代码就变为:
lea eax, [ebp - $ 08 ]
mov edx, [ebp
- $ 04 ]
mov ecx, $00452bc4
call @IntfCast
mov eax, [ebp
- $ 08 ]
mov edx, [eax]
call dword prt [edx
+ $0c]

发现,在用as标志转化后,就会使编译器知道要在类实例中查找实际的接口ITestInterface2而不是用mInt所声明的ITestInteface.

以上说明Delphi7的编译器对接口的支持还是不够好,造成在强制转化时,不能正确的识别出要求的接口类型来. 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值