gpt4 book ai didi

delphi - 为什么 `as` 运算符可能会抛出令人讨厌的 EAccessViolation 而不是正常的 EIntfCastError ?

转载 作者:行者123 更新时间:2023-12-03 15:28:53 26 4
gpt4 key购买 nike

我制作了高度实验性且不稳定的 IDE 插件,这会在 IDE 关闭时导致极其令人讨厌的 A/V(破坏了最近的项目功能,糟糕!)。我最终将范围缩小到特定的析构函数:

destructor TMyAddIn.Destroy;
begin
{$IFDEF DEBUG}
{ BUG is here, causes A/V at shutdown }
(BorlandIDEServices as IOTAMessageServices).AddTitleMessage('Goodbye');
{$ENDIF}

{ ... }
{ finalizing stuff }
{ ... }

inherited;
end;

读取地址 0x00000008 时发生 A/V 异常。

我为有问题的陈述添加了更多防御措施:

  if Assigned(BorlandIDEServices) then    { passes }
if Supports(BorlandIDEServices, IOTAMessageServices) then { fails }
(BorlandIDEServices as IOTAMessageServices).AddTitleMessage('Goodbye');

...并弄清楚 (1) 指针仍然不是 nil (2) QueryInterface 仍然有效 (3) 所需的接口(interface)不再存在。鉴于一切看起来都很正常,我期望友好的 EIntfCastError。但为什么我有 A/V 呢?

最佳答案

我的猜测是

  1. BorlandIDEServices 本身不为零,但也不再有效

  2. BorlandIDEServices 有效,但其内部 IOTAMessageServices 实现无效。

这些可能会导致读取地址 0x00000008 错误。

您应该做的是在加载项生命周期的早期获取 IOTAMessageServices 接口(interface)并保留它,这样由于引用计数,它在析构函数中仍然有效,例如:

{$IFDEF DEBUG}
private
MsgSvc: IOTAMessageServices;
{$ENDIF}

constructor TMyAddIn.Create;
begin
inherited;

{ ... }
{ initializing stuff }
{ ... }

{$IFDEF DEBUG}
MsgSvc := BorlandIDEServices as IOTAMessageServices;
MsgSvc.AddTitleMessage('Hello');
{$ENDIF}
end;

destructor TMyAddIn.Destroy;
begin
{$IFDEF DEBUG}
MsgSvc.AddTitleMessage('Goodbye');
{$ENDIF}

{ ... }
{ finalizing stuff }
{ ... }

inherited;
end;

关于delphi - 为什么 `as` 运算符可能会抛出令人讨厌的 EAccessViolation 而不是正常的 EIntfCastError ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23207796/

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