S
shenloqi
Unregistered / Unconfirmed
GUEST, unregistred user!
这只是一个关于引用计数的例子,Delphi的Interface以及string还有动态数组等等都是
自动处理引用计算的,有时候会希望在变量超出范围之后保留一个指向一个字符串或接口
的引用。(例如:可能需要将一个接口与一个TListview中的每一个元素联系起来,好像
有一些牵强,不过我觉得主要是用来学习引用计数的,呵呵)可以通过显式地管理引用计
算来做到这一点。存储接口时,务必把它转换为IUnknown,调用_AddRef,并将IUnknown
引用转换为一个原始指针。析取数据时,将指针类型转换为IUnknown,然后可以用as运算
符来将接口转换为任何想要的类型(或只让Delphi释放该接口)。下面是一个在ListView
中存储接口的例子。(非本人创作,只是共同学习)
同样的方法可以对于字符串等使用,例子就省略了(基本同上)。
自动处理引用计算的,有时候会希望在变量超出范围之后保留一个指向一个字符串或接口
的引用。(例如:可能需要将一个接口与一个TListview中的每一个元素联系起来,好像
有一些牵强,不过我觉得主要是用来学习引用计数的,呵呵)可以通过显式地管理引用计
算来做到这一点。存储接口时,务必把它转换为IUnknown,调用_AddRef,并将IUnknown
引用转换为一个原始指针。析取数据时,将指针类型转换为IUnknown,然后可以用as运算
符来将接口转换为任何想要的类型(或只让Delphi释放该接口)。下面是一个在ListView
中存储接口的例子。(非本人创作,只是共同学习)
代码:
{-----------------------------------------------------------------------------
Procedure: RefIUnknown
Author: slq
Date: 22-三月-2002
Arguments: const Intf: IUnknown
Result: Pointer
Purpose: 保存接口到一个指针,增加引用计数。
-----------------------------------------------------------------------------}
function RefIUnknown(const Intf: IUnknown): Pointer;
begin
//增加引用计数
Intf._AddRef;
//保存接口指针
Result := Pointer(Intf);
end;
{-----------------------------------------------------------------------------
Procedure: ReleaseIUnknown
Author: slq
Date: 22-三月-2002
Arguments: P: Pointer
Result: None
Purpose: 释放保存在指针中的接口
-----------------------------------------------------------------------------}
procedure ReleaseIUnknown(P: Pointer);
var
Intf: IUnknown;
begin
Pointer(Intf) := P;
//Delphi会在子程序结束后自动释放借口
end;
{-----------------------------------------------------------------------------
Procedure: TForm1.Button1Click
Author: slq
Date: 22-三月-2002
Arguments: Sender: TObject
Result: None
Purpose: 增加接口到列表
-----------------------------------------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
Item: TListItem;
begin
Item := ListView1.Items.Add;
Item.Caption := 'Hello, World!';
Item.Data := RefIUnknown(GetIntf as IUnknown);
end;
{-----------------------------------------------------------------------------
Procedure: TForm1.ListView1Deletion
Author: slq
Date: 22-三月-2002
Arguments: Sender: TObject
Item: TListItem
Result: None
Purpose: 释放列表项目的时候一定要记得释放接口
-----------------------------------------------------------------------------}
procedure TForm1.ListView1Deletion(Sender: TObject
Item: TListItem);
begin
ReleaseIUnknown(Item.Data);
end;
{-----------------------------------------------------------------------------
Procedure: TForm1.ListView1Click
Author: slq
Date: 22-三月-2002
Arguments: Sender: TObject
Result: None
Purpose: 用户对列表的操作就相当于对接口的操作
-----------------------------------------------------------------------------}
procedure TForm1.ListView1Click(Sender: TObject);
var
Intf: IMyInterface;
begin
Intf := IUnknown(ListView1.Selected.Data) as IMyInterface;
Intf.DoSomethingUseful;
end;
同样的方法可以对于字符串等使用,例子就省略了(基本同上)。