gpt4 book ai didi

delphi - 最后一次 IUnknown.Release 调用的时刻

转载 作者:行者123 更新时间:2023-12-03 14:48:31 26 4
gpt4 key购买 nike

我有相同代码的两个变体:

{$APPTYPE CONSOLE}

uses
System.SysUtils;

type
IMyObject1 = interface
['{4411181F-3531-4D30-AB18-A8326F8C2CD0}']
end;

IMyObject2 = interface
['{41C88E1A-0360-4AC3-B021-125880B23DE5}']
end;

TMyObject = class(TInterfacedObject, IMyObject1, IMyObject2)
public
destructor Destroy; override;
end;


destructor TMyObject.Destroy;
begin
Writeln('Destroy');
inherited;
end;

procedure Variant1;

function GetMyObject: IMyObject2;
var
Obj1: IMyObject1;
begin
Obj1 := TMyObject.Create;
try
Obj1.QueryInterface(IMyObject2, Result);
finally
Obj1 := nil;
end;
end;

var
Obj2: IMyObject2;
begin
Obj2 := GetMyObject;
try
finally
Obj2 := nil;
end;
Writeln('Variant1 end of proc');
end;

function GetMyObject: IMyObject2;
var
Obj1: IMyObject1;
begin
Obj1 := TMyObject.Create;
try
Obj1.QueryInterface(IMyObject2, Result);
finally
Obj1 := nil;
end;
end;

procedure Variant2;
var
Obj2: IMyObject2;
begin
Obj2 := GetMyObject;
try
finally
Obj2 := nil;
end;
Writeln('Variant2 end of proc');
end;

begin
Variant1;
Writeln('---');
Variant2;
Writeln('---');
Readln;
end.

输出

Variant1 end of procDestroy---DestroyVariant2 end of proc---

为什么两个变体的行为不同?

最佳答案

测试环境:Delphi XE7 Windows编译器

Variant1中,编译器决定需要创建一个隐式局部变量来保存额外的接口(interface)引用。我无法辨别为什么会这样。但这里发出的代码表明这就是发生的情况:

变体1

Project1.dpr.46: Obj2 := GetMyObject;0041A3BD 55               push ebp0041A3BE 8D45F8           lea eax,[ebp-$08]0041A3C1 E836FFFFFF       call GetMyObject0041A3C6 59               pop ecx0041A3C7 8B55F8           mov edx,[ebp-$08]0041A3CA 8D45FC           lea eax,[ebp-$04]0041A3CD E816F5FEFF       call @IntfCopy      // copies into the implicit local

变体2

Project1.dpr.70: Obj2 := GetMyObject;0041A53B 8D45FC           lea eax,[ebp-$04]0041A53E E839FFFFFF       call GetMyObject    // no such copy here

隐式局部变量在声明它们的函数的最后完成,就像任何其他局部变量一样。这就是为什么 Writeln('Variant1 end of proc') 执行,然后隐式局部被最终确定,然后释放对该对象的最终引用。

这里非常有趣的一个因素是,如果您启用优化,那么输出将更改为:

DestroyVariant1 end of proc---DestroyVariant2 end of proc---

出于某种原因,编译器决定在启用优化时不创建隐式局部变量。

当然,以上都是针对32位编译器的。 64位编译器又不一样了,你难道不知道吗?在 64 位编译器中,无论优化如何,输出都是按照问题进行的。

我认为这个问题可能与我的问题Is the compiler treatment of implicit interface variables documented?有关据我所知,没有关于编译器功能的官方规范或文档,您在这里所能做的最好的事情就是通过观察其输出来进行经验学习。优化会改变行为意味着您应该尝试避免容易受到此类行为变化影响的代码。如果你确实可以预测它们的话。

关于delphi - 最后一次 IUnknown.Release 调用的时刻,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31108871/

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