使用Delphi 10.2 Tokyo,我有一个带有自定义类的单元(不是表单或数据模块)。在这个类中,我使用XML文档 - 出于DB数据的导出 - 如下:
TMyClass = class(TObject)
private
...
FDocument: IXMLDocument;
...
protected
...
public
...
end;
constructor TMyClass.Create(ADBConnection: TAdsConnection);
begin
...
FDocument := TXMLDocument.Create(nil);
...
end;
此类的一般功能是执行查询并将结果写入FDocument
,保存到文件等。
在开设这门课程的同时,一切都运转良好。现在我想在FDocument := TXMLDocument.Create(nil)
语句中添加一些查询语句(DB中的新表)和代码崩溃(访问冲突)。我只能使用nil
作为参数,因为我的课程不包含任何TComponent
。
互联网搜索为我提供了多条线索,将FDocument
声明为IXMLDocument
(而不是TXMLDocument
)并引用计数(将nil
作为所有者传递),但我认为这些这里不适用有两个原因:
FDocument
IS 声明为IXMLDocument
,并且在我释放(销毁)TMyClass
之前不会超出范围(即没有Free
或类似的。
执行语句FDocument := TXMLDocument.Create(nil)
时发生访问冲突,此后不再发生。因此,我认为FDocument
甚至没有初始化,也不应该影响接口引用计数。
在我开发TMyClass
和发生此问题之间唯一改变的是我的PC升级到Windows 10 Fall Creator(版本1703 - > 1709)。
任何人都可以告诉我可能导致此问题的原因吗?它可能是缺少库(窗口更新)还是远远不够?请注意这是我第一次使用XML,所以我可能会错过明显的....
答案 0 :(得分:0)
问题已解决:
创建了一个包含新类(TTestClass
)的单元,该类只有一个字段FDocument
(即类似于TMyClass
,但所有其他内容都被删除了)。从测试应用中,创建TTestClass
没问题;即使是Create(nil)
。
然后我尝试从测试应用中创建TMyClass
。和以前一样,这与AV一起坠毁。确切地说;在System._IntfCopy
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._Release
。不幸的是,我不了解汇编,所以我决定查看TTestClass
和TMyClass
之间的“不同代码”。
这个问题的根源证明是一个愚蠢的错误。查询语句(用于按描述导出数据)保存在静态对象数组中。我添加了查询对象,但忘了增加数组的维度(即声明的数组小于我试图存储的对象数)。
我不明白的是,这会导致TXMLDocument.Create(nil)
失败。我在创建IXMLDocument
之前填充数组,所以我希望数组的“索引超出范围”错误(例如在FMyArray[**5**]
上使用FMyArray: array [0 .. **4**] of TMyObject;
)。但是,这并没有发生,并且在尝试创建IXMLDocument
时引发了AV。