gpt4 book ai didi

Delphi 对象、NIL 对象和接口(interface)

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

我正在寻找有关如何调试在 Delphi VCL 中使用 MS XML 包装器的应用程序中的崩溃的提示。我怀疑内存损坏,或者对象和接口(interface)之间发生了某种晦涩难懂的邪恶事情,例如引用计数错误或堆损坏。实际上,问题是:如何调试此类崩溃?

此特定代码大量内部使用并扩展了基本 XmlIntf 接口(interface) (IXMLNode)。 ISomethingCustom 是扩展 IXMLNode 的接口(interface)。当我们在递归函数中的某个地方崩溃时,就会出现问题,该函数传递了一个 ISomethingCustom,该 ISomethingCustom 也是(或在接口(interface)方面也支持)IXMLNode。

   boolean UtilityFunction( aNode: ISomethingCustom ):Boolean;
begin
if not Assigned(aNode) then exit; // this works. great.
if not Assigned(aNode.ParentNode) then exit; // this DOES NOT WORK.
// code that blows up if aNode.ParentNode is not assigned.
end;

情况是 aNode 也是 IXMLNode,并且分配了 IXMLNode.ParentNode 值(不是 nil),但它指向一个可能已被释放、销毁或以某种方式损坏的 COM 对象。我试图弄清楚当接口(interface)指针看似有效但其背后的对象已被某种方式破坏时发生了什么。

检查Assigned(aNode.ParentNode)会返回TRUE,即使您尝试在调试器中进行强制转换(仅在运行时,而不是在代码中),如下所示:

  1. 检查/评估节点
  2. 检查/评估 TInterfacedObject(aNode).ClassName(至少可以在 Delphi 2010 中运行!)
  3. 现在强制转换 TWhateverClassNameYouGotBefore(aNode)。
  4. 在调试器中我现在看到这是 NIL。这可能意味着神奇的“施法界面”回到对象”的新功能delphi 2010,失败了。

我相信我正在尝试调试因引用计数问题而导致堆损坏或 COM 对象在堆上损坏的问题。

我真的认为任何人都不应该出现界面看似有效但底层对象已被删除的情况。我真的很想知道该怎么办,以及发生了什么事。

最佳答案

尽管您没有在代码中显示它,但您的注释似乎表明您正在将接口(interface)变量类型转换为类类型。这是不允许的。我已经描述了原因:

接口(interface)引用和对象引用并不指向相同的东西。因此,当编译器认为您有另一个方法时,调用其中一个方法会产生意外结果。您很不幸,因为代码继续运行,而不是因访问冲突而崩溃,这更能表明您做错了什么。

我上面的文章最后建议您使用 JCL 中的 JclSysUtils​.GetImplementorOfInterface 函数如果您有一个 Delphi 实现的接口(interface),并且该接口(interface)没有提供自己的功能来显示底层对象。

关于Delphi 对象、NIL 对象和接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3678710/

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