gpt4 book ai didi

delphi - 如何通过避免调用 _Release 来混合接口(interface)和类?

转载 作者:行者123 更新时间:2023-12-03 18:28:56 24 4
gpt4 key购买 nike

在 Delphi 中使用接口(interface)并覆盖引用计数时,可以绕过 Delphi 在接口(interface)达到引用计数为零时进行的_Release 调用。

但是 - 当混合类和接口(interface)(这非常有用)时,_Release 方法总是被调用,无论如何。问题是在下面的示例代码中,本地对象是 nill-ed,但 _Release 仍然被调用 - 除了在无效内存上。根据应用程序中的内存操作,当在 nilled localObject 的旧位置调用 _Release 时可能会导致异常,如果内存没有被重新使用,则不会出现异常。

那么,编译器生成的对 _Release 的调用是否可以“删除/阻止/避免/杀死/重定向/vmt 劫持/终止/smacked/etc 等等”?如果这可以实现,那么您在 Delphi 中有适当的纯接口(interface)。

unit TestInterfaces;

interface

uses
Classes,
SysUtils;

type

ITestInterface = interface
['{92D4D6E4-A67F-4DB4-96A9-9E1C40825F9C}']
procedure Run;
end;

TTestClass = class(TInterfacedObject, ITestInterface)
protected
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure Run;
end;

TRunTestClass = class(TObject)
protected
FlocalInterface : ITestInterface;
FlocalObject : TTestClass;
public
constructor Create;
destructor Destroy; override;
procedure Test;
end;

procedure RunTest;
procedure RunTestOnClass;

var
globalInterface : ITestInterface;

implementation


procedure RunTest;
var
localInterface : ITestInterface;
localObject : TTestClass;
begin

try

//create an object
localObject := TTestClass.Create;

//local scope
// causes _Release call when object is nilled
localInterface := localObject;
localInterface.Run;

//or global scope
// causes _Release call when exe shuts down - possibly on invalid memory location
globalInterface := localObject;
globalInterface.Run;

finally
//localInterface := nil; //--> forces _Release to be called
FreeAndNil( localObject );
end;

end;

procedure RunTestOnClass;
var
FRunTestClass : TRunTestClass;
begin
FRunTestClass := TRunTestClass.Create;
FRunTestClass.Test;
FRunTestClass.Free;
end;


{ TTheClass }

procedure TTestClass.Run;
begin
beep;
end;

function TTestClass._AddRef: Integer;
begin
result := -1;
end;

function TTestClass._Release: integer;
begin
result := -1;
end;

{ TRunTestClass }

constructor TRunTestClass.Create;
begin
FlocalObject := TTestClass.Create;
FlocalInterface := FlocalObject;
end;

destructor TRunTestClass.Destroy;
begin
//..
FlocalObject.Free;
//FlocalObject := nil;
inherited;
end;

procedure TRunTestClass.Test;
begin
FlocalInterface.Run;
end;

end.

最佳答案

没有实用的方法来实现您正在寻找的东西。编译器将发出对 _Release 的调用。为了打击他们,您需要找到所有调用站点。这不切实际。

恐怕禁用引用计数生命周期管理时唯一可行的方法是确保在调用 nil 之前完成(即设置为 Free )所有接口(interface)引用.

关于delphi - 如何通过避免调用 _Release 来混合接口(interface)和类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7316871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com