托管类型对其引用进行计数,当计数降至零时,它们将被最终确定。如果你有一个局部变量,那么当它超出范围时,它的引用计数将下降到零。
TInterfacedObject
因此,您可以使用接口创建您引用的后代。像这样的东西:
type
TLifetimeWatcher = class(TInterfacedObject)
private
FDestroyProc: TProc;
public
constructor Create(const DestroyProc: TProc);
destructor Destroy; override;
end;
constructor TLifetimeWatcher.Create(const DestroyProc: TProc);
begin
inherited Create;
FDestroyProc := DestroyProc;
end;
destructor TLifetimeWatcher.Destroy;
begin
if Assigned(FDestroyProc) then
FDestroyProc();
inherited;
end;
然后你可以像这样使用它:
procedure MyProcedure;
var
MyPointer: Pointer;
LifetimeWatcher: IInterface;
begin
MyPointer := VirtualAlloc (NIL, 1024, MEM_COMMIT or MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
LifetimeWatcher := TLifetimeWatcher.Create(
procedure
begin
VirtualFree(MyPointer, 0, MEM_RELEASE);
end;
)
FillMemory(MyPointer);
end;
当LifetimeWatcher
离开作用域时,实现对象被销毁并执行您传递给的过程TLifetimeWatcher.Create
。
将这个想法专门用于您的用例将很容易。这将使呼叫站点的代码更加简洁。
看起来像这样:
function VirtualAllocAutoRelease(Size: SIZE_T; Protect: DWORD;
out LifetimeCookie: IInterface): Pointer;
var
Ptr: Pointer;
begin
Ptr := VirtualAlloc(nil, Size, MEM_COMMIT or MEM_RESERVE, Protect);
Win32Check(Ptr<>nil);
LifetimeCookie := TLifetimeWatcher.Create(
procedure
begin
VirtualFree(Ptr, 0, MEM_RELEASE);
end
);
Result := Ptr;
end;
你会像这样使用它:
procedure MyProcedure;
var
MyPointer: Pointer;
LifetimeWatcher: IInterface;
begin
MyPointer := VirtualAllocAutoRelease(1024, PAGE_EXECUTE_READWRITE,
LifetimeWatcher);
FillMemory(MyPointer);
end;