此特定代码在基本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实现的接口,并且接口没有提供它自己的功能来揭示底层对象.