Нарушение доступа при доступе к элементу документа в XMLDocument

У меня возникла ошибка нарушения прав доступа при попытке доступа к элементу документа XMLDocument. Я создаю объект XMLDocument в зависимости от существования какого-либо файла. Сообщение об ошибке:

Project project1.exe поднял класс исключений EAccessViolation с сообщением "Нарушение прав доступа по адресу 0047B152 в модуле" project1.exe ". Чтение адреса B1D59357"

Ниже приведен мой код:

unit XMLBase;

interface
uses
  SysUtils, xmldom, XMLIntf, XMLDoc, Forms;

type
  TXMLbase = class
  private
    { Private declarations }
  public
    XMLDocument1: TXMLDocument;
    root: IXMLNode;    
    constructor Create;
  end;
var
  fn: string;

implementation

constructor TXMLbase.Create;
begin   
  fn := ChangeFileExt(Application.ExeName, '.xml');
  XMLDocument1 := TXMLDocument.Create(nil);
  XMLDocument1.Options := [doNodeAutoIndent];
  XMLDocument1.Active := False;
  //optional, is used to indent the Xml document
  if FileExists(fn) then
  begin
  XMLDocument1.LoadFromFile(fn);
  XMLDocument1.Active:= True;
  root := XMLDocument1.DocumentElement;  //<<--- Access Voilation
  end
  else
  begin
    XMLDocument1.Active := False;
    XMLDocument1.XML.Text := '';
    XMLDocument1.Active := True;
    root := XMLDocument1.AddChild('Settings');    
  end;
XMLDocument1.SaveToFile(fn);
end;
end.

Нарушения прав доступа возникают из-за неправильной инициализации объекта или указателей. Означает ли это, что XMLDocument не инициализируется? Пожалуйста помоги.

2 ответа

Решение

Как указывает Дэвид, просто меняя объявление XMLDocument1 с XMLDocument1: TXMLDocument в XMLDocument1: IXMLDocument решает проблему. Ваша проблема связана с использованием TXmlDocument

Вы проходите nil в TXMLDocument.Create, Когда вы делаете это, объект ведет себя как TInterfacedObject, Это время жизни управляется подсчетом ссылок интерфейса. Но вы не держите ссылку на интерфейс.

Документация охватывает это в некоторых деталях.

Когда TXMLDocument создается без владельца, он ведет себя как интерфейсный объект. То есть, когда все ссылки на его интерфейс освобождаются, экземпляр TXMLDocument автоматически освобождается. Однако когда TXMLDocument создается с владельцем, он ведет себя как любой другой компонент и освобождается его владельцем.

Если вы включите отладку DCU и установите точку останова в TXMLDocument.Destroy Вы можете наблюдать, как объект разрушается непосредственно перед нарушением вашего доступа.

Решите проблему:

  1. Передача владельца при создании документа.
  2. Переключитесь на использование интерфейсов для ссылки на объект. Это объявить XMLDocument1 как IXMLDocument,

Убедитесь, что вы делаете один или другой из них, но не оба!

Другие вопросы по тегам