7

のを使用しようとすると、常にアクセス違反が発生しDocumentElementますXMLDocumentXMLDocumentなんらかのファイルの存在に基づいて作成します。

エラーメッセージ

プロジェクトproject1.exeは、メッセージ「モジュール'project1.exe'のアドレス0047B152でのアクセス違反」で例外クラスEAccessViolationを発生させました。アドレス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ます。これは、が初期化されていないことを意味しますか?

4

2 に答える 2

10

あなたはに渡しnilていTXMLDocument.Createます。これを行うと、オブジェクトはのように動作しますTInterfacedObject。その存続期間は、インターフェース参照カウントによって管理されます。しかし、あなたはインターフェースへの参照を保持していません。

ドキュメントはこれをいくらか詳細にカバーしています。

TXMLDocumentが所有者なしで作成されると、インターフェイスオブジェクトのように動作します。つまり、そのインターフェイスへのすべての参照が解放されると、TXMLDocumentインスタンスは自動的に解放されます。ただし、TXMLDocumentが所有者とともに作成されると、他のコンポーネントと同じように動作し、所有者によって解放されます。

デバッグDCUを有効にしてブレークポイントを設定するとTXMLDocument.Destroy、アクセス違反の直前にオブジェクトが破棄されるのを確認できます。

次のいずれかで問題を解決します。

  1. ドキュメントを作成するときに所有者を渡す。
  2. オブジェクトを参照するためにインターフェースを使用するように切り替えます。それはとして宣言XMLDocument1されIXMLDocumentます。

これらのいずれかを実行するようにしてください。両方は実行しないでください。

于 2012-12-25T15:51:22.173 に答える
3

Davidが示しているように、XMLDocument1宣言をからXMLDocument1: TXMLDocumentに変更するだけXMLDocument1: IXMLDocumentで問題が解決します。あなたの問題はTXmlDocumentの使用に関連しています

于 2012-12-25T17:08:13.220 に答える