关于基于Delphi平台的接口编程入门
为什么要使用界面?
举个例子:有这样一个售票服务,就是电*可以售票,歌剧院可以售票,客运站也可以售票。那么,我们是否需要将电力*、歌剧院、客运站设计成一个类架构来提供售票服务呢?要知道,连经理都能卖票。显然,不适合将管理者纳入票务服务的继承结构中。我们需要的是一种通用的售票服务。所以卖票的服务就是一个接口,只要电力、歌剧院等等遵循这样一个服务定义,就可以很好的相互交互和沟通(如果需要的话)。
如何在Delphi中使用界面
1.声明接口
iminterface = interface(IInterface)//描述(1)
[' { 63e 072 df-B81e-4734-B3CB-3c 23c 7 FDA 8 ea } ']//描述(2)
函数GetName(conststr:string):string stdcall;
函数QueryInterface(常量IID:TGUID;out Obj):HResult;stdcall//描述(3)
Function _ Addref:integer;stdcall//将接口引用的数量增加1。
function _ Release:Integer;stdcall//接口引用数减1,小于等于0时释放。
end;
注(1):如果有延续关系,则在括号内填写父接口,否则省略,如:IMyInterface = interface。
注意(2):此GUID是可选的。如果要实现具有COM特性的接口,需要添加。对于Delphi中带有GUID的接口,运行时会在VMT表的预定位置生成接口信息,比如接口方法的定义,方法参数的定义。
解释(3):接口必须实现这三个功能。
2.接口的实现
接口由类实现。
TIntfClass = class(to object,IMyInterface)
私人的
FCounter:整数;
FRefCount:整数;
公众的
函数QueryInterface(常量IID:TGUID;out Obj):HResult;stdcall
...
结束;
3.获取接口
A.使用类型转换。比如:
var aIntf:imy interface;
开始
aObj := TIntfClass。创建;
尝试
aIntf:=(IMyInterface(aObj);
...
B.使用Delphi编译器的内置机制。例如aIntf := aObj。
C.使用对象的QueryInterface方法。例如ole check (aobj.query接口(iid,aintf));只能访问GUID为的COM接口。
D.使用as运算符。
使用as运算符必须满足以下条件:
1.该接口必须显式指定为从IInterface接口继承。
2.您必须有GUID值
在Delphi7中,接口的实现类也必须从TInterfacedObject继承,比如:
TIntfClass = class(TInterfacedObject,IMyInterface)
4.接口和对象的生存期
因为Delphi会自己检查接口,如果使用后没有发布,会在生成的程序中添加发布代码,但是也带来了问题,比如下面的代码:
var
i:整数;
aObj:TIntfClass;
aIntf:imy interface;
begin
aObj:= TIntfclass。创建;
try
aIntf:= aObj;
aIntf。获得名字...
最后
aIntf:= nil;
FreeAndNil(aObj);
end;
如果执行上面的代码,会产生访问冲突错误,因为在接口上设置nil时接口已经被释放,FreeAndNil(aObj)会再次释放aIntf,同时设置aIntf。
该对象已被释放为零。要解决这个问题,我们只需要让接口不干扰对象的生存期。在Release中,我们只需要减少引用计数而不需要释放它。
函数TIntfClass。_Release:整数;
开始
结果:= InterlockedDecrement(fref count);
结束;
0条评论