微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Delphi对象,NIL对象和接口

我正在寻找有关如何在Delphi VCL中使用MS XML包装器的应用程序中调试崩溃的提示.我怀疑内存损坏,或对象和接口之间发生某种模糊的邪恶事件,例如引用计数错误或堆损坏.问题是,实际上:我如何调试这样的崩溃?

此特定代码在基本XmlIntf接口(IXMLNode)上进行了大量内部使用和扩展. ISomethingCustom是一个扩展IXMLNode的接口.问题发生在我们在递归函数中的某个地方崩溃,该函数传递了一个ISomethingCustom,它也是(或者也支持,在接口术语中)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对象.我试图弄清楚当接口指针看起来有效时会发生什么,但它背后的对象已经被某种方式破坏了.

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

>检查/评估aNode
>检查/评估TInterfacedobject(aNode).ClassName
(至少在Delphi 2010中工作!)
>现在施放TWhateverClassNameYouGotBefore(aNode).
>在调试器中,我现在看到这是NIL.这可能意味着什么
神奇的“铸造界面回归
对象“新功能
delphi 2010,正在失败.

我相信我正在尝试调试堆损坏,或者COM对象在堆上损坏的问题,因为引用计数问题.

我真的认为没有人应该出现界面显示有效的情况,但下面的对象已被删除.我真的很想知道该做什么,以及发生了什么.

解决方法

虽然您没有在代码显示它,但您的注释似乎表明您正在将接口变量压缩为类类型.这是不允许的.我已经描述了原因:

> Why can’t I cast an interface reference to an object reference?

接口引用和对象引用并不指向相同的东西.因此,当编译器认为您拥有另一个时,调用一个方法将产生意外结果.你运气不好是因为代码继续运行而不是因访问冲突而崩溃,这可能是你做错事的一个更大的迹象.

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

原文地址:https://www.jb51.cc/delphi/239348.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐