gpt4 book ai didi

Delphi "Supports"增加[弱]或[不安全]接口(interface)上的引用计数

转载 作者:行者123 更新时间:2023-12-03 14:40:19 24 4
gpt4 key购买 nike

当我使用 Delphi Berlin 10.1 [弱](和[不安全])引用时,当给定标有“弱”属性的接口(interface)变量时,“Supports”函数和“QueryInterface”都会增加引用计数(相同)具有“不安全”属性的行为)。

program WeakReferences;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.SysUtils;

type
IAnInterfacedObject = interface
['{351DFDA3-42CA-4A1D-8488-494CA454FD9C}']
end;

TAnInterfacedObject = class(TInterfacedObject, IAnInterfacedObject)
protected

function GetTheReferenceCount : integer;

public
constructor Create;
destructor Destroy; override;
property TheReferenceCount : integer read GetTheReferenceCount;
end;

constructor TAnInterfacedObject.Create;

begin
inherited Create;
writeln('(create AIO instance)');
end;

destructor TAnInterfacedObject.Destroy;

begin
writeln('(destroy AIO instance)');

inherited Destroy;
end;

function TAnInterfacedObject.GetTheReferenceCount : integer;

begin
Result := FRefCount;
end;

procedure WithoutSupports;

var
AIOinstance : TAnInterfacedObject;

AIOinterfaced : IAnInterfacedObject;

[Weak]
WeakAIOinterfaced : IAnInterfacedObject;

begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);

AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);

WeakAIOinterfaced := AIOinstance;
writeln('create WEAK AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;

procedure WithSupports_Weak;

var
AIOinstance : TAnInterfacedObject;

AIOinterfaced : IAnInterfacedObject;

[Weak]
WeakAIOinterfaced : IAnInterfacedObject;

begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);

AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);

Supports(AIOinstance, IAnInterfacedObject, WeakAIOinterfaced);
writeln('create WEAK AIO interfaced with SUPPORTS; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;

procedure WithSupports_Unsafe;

var
AIOinstance : TAnInterfacedObject;

AIOinterfaced : IAnInterfacedObject;

[Unsafe]
UnsafeAIOinterfaced : IAnInterfacedObject;

begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);

AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);

Supports(AIOinstance, IAnInterfacedObject, UnsafeAIOinterfaced);
writeln('create UNSAFE AIO interfaced with SUPPORTS; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;

procedure WithQueryInterface_Weak;

var
AIOinstance : TAnInterfacedObject;

AIOinterfaced : IAnInterfacedObject;

[Weak]
WeakAIOinterfaced : IAnInterfacedObject;

begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);

AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);

AIOinterfaced.QueryInterface(IAnInterfacedObject, WeakAIOinterfaced);
writeln('create WEAK AIO interfaced with QUERYINTERFACE; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;

begin
try
writeln('--Without "Supports"-------------------');
WithoutSupports;
writeln;
writeln('--With "Supports" - weak-------------------');
WithSupports_Weak;
writeln;
writeln('--With "Supports" - unsafe-------------------');
WithSupports_Unsafe;
writeln;
writeln('--With "QueryInterface" - weak-------------------');
WithQueryInterface_Weak;

except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;

readln;
end.

我在这里错过了什么?有“WeakSupports”功能吗?这是一个错误还是只是新的“弱”接口(interface)功能的缺点?

最佳答案

Delphi Supports(重载之一 - 但考虑到 out 参数,所有其他都相同)函数声明为

function Supports(const Instance: IInterface; const IID: TGUID; out Intf): Boolean;

QueryInterface

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

两个 out 参数均未标记为 [weak]。这意味着您无法将 [weak][unsafe] 接口(interface)引用传递给它们。您只能传递对此类参数的强引用以保持引用计数的顺序。

来自文档 Weak References :

Note: You can only pass a [Weak] variable to a var or out parameter that is also marked as [Weak]. You cannot pass a regular strong reference to a [Weak] var or out parameter.

Note: You can only pass an [Unsafe] variable to a var or out parameter that is also marked as [Unsafe]. You cannot pass a regular strong reference to an [Unsafe] var or out parameter.

<小时/>

此外,您的测试用例还有另一个问题。除非您使用完整的 ARC Delphi 编译器(当前为 Android 和 iOS),否则您无法存储引用计数的对象到对象的引用,否则您将搞乱引用计数。更准确地说,非 ARC 编译器下的对象引用对引用计数没有贡献,只能将它们用作临时访问点,对无法通过声明的接口(interface)访问的对象执行一些操作。您应该始终至少有一个对该对象实例的接口(interface)引用,以保持引用计数有序,并防止过早的对象销毁或内存泄漏。

而不是

 var
AIOinstance : TAnInterfacedObject;
...
AIOinstance := TAnInterfacedObject.Create;

你应该始终使用

var
AIOinstance : IAnInterfacedObject;
...
AIOinstance := TAnInterfacedObject.Create;

关于Delphi "Supports"增加[弱]或[不安全]接口(interface)上的引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42303179/

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