![]() |
Delphi-Version: 5
Kann ich das IntfClear vorziehen?
Disclaimer:
Delphi-Quellcode:
uses Xml.XmlIntf, Xml.XmlDoc, Winapi.ActiveX
Folgender Quellcode verursacht eine Zugriffsverletzung:
Delphi-Quellcode:
Warum? Weil das "anonym" erzeugte XML-Dokument nicht nach dem CoUninitialize() freigegeben werden darf. Das geschieht aber weil der Compiler (für uns unsichtbar) nach dem "end;" der Methode noch Code einfügt um ein
procedure myProc();
begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try NewXMLDocument(); finally CoUninitialize() end; end;
Delphi-Quellcode:
auf dem anonymen
_Release
Delphi-Quellcode:
aufzurufen.
IXMLDocument
Was tun wir also? Wir nehmen uns eine Variable und geben es manuell frei:
Delphi-Quellcode:
Eigentlich könnten wir jetzt Feierabend machen. Doch wenn es sich so einfach lösen ließe, müsste folgendes ja auch gehen, oder?
procedure myProc2();
var xmlDoc: IXMLDocument; begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try xmlDoc := NewXMLDocument(); xmlDoc := nil; finally CoUninitialize() end; end;
Delphi-Quellcode:
Leider haben wir hier unsere alte AV wieder zurück. Komisch, wir haben doch das IXMLDocument und die IXMLNode freigegeben. Leider nicht, denn anonym haben wir uns mit
procedure myProc3();
var xmlDoc: IXMLDocument; xmlNode: IXMLNode; begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try xmlDoc := LoadXMLData('<rootNode />'); xmlNode := xmlDoc.DocumentElement.AddChild('someChildNode'); xmlDoc := nil; xmlNode := nil; finally CoUninitialize() end; end;
Delphi-Quellcode:
wieder eine anonyme
.DocumentElement
Delphi-Quellcode:
eingehandelt.
IXMLNode
Man könnte nun entweder die Sache mit wachsamen Augen und einem Sack voller unnötiger Variablen bekämpfen oder man macht es folgenderweise:
Delphi-Quellcode:
procedure doXmlStuff();
var xmlDoc: IXMLDocument; begin xmlDoc := LoadXMLData('<rootNode />'); xmlDoc.DocumentElement.AddChild('someChildNode'); xmlDoc := nil; end; procedure myProc(); begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try doXMLStuff(); finally CoUninitialize() end; end; Daher meine Frage: Kann ich das vermeiden? Kann ich das IntfClear am Ende einer Methode vorziehen? Dann bräuchte ich die Extramethode nicht. Dies war ein kostenloser Probeartikel aus der Reihe Probleme welche die Welt bewegen. |
AW: Kann ich das IntfClear vorziehen?
Zitat:
Internen Temp-Variablen kannst du nicht freigeben, da du nicht an deren Variablen ran kommst. Einzige Lösungen:
Keine Aufrufketten (maximal 1 Punkt pro Ausdruck, abgesehn von Namespaces) und alle Results selbst behandeln.
Delphi-Quellcode:
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
try xmlDoc := LoadXMLData('<rootNode />'); xmlRoot := xmlDoc.DocumentElement; xmlNode := xmlRoot.AddChild('someChildNode'); xmlNode := nil; xmlRoot := nil; xmlDoc := nil; finally CoUninitialize; end;
Delphi-Quellcode:
{procedure doXmlStuff;
var xmlDoc: IXMLDocument; begin xmlDoc := LoadXMLData('<rootNode />'); xmlDoc.DocumentElement.AddChild('someChildNode'); //xmlDoc := nil; end;} procedure doXmlStuff; begin LoadXMLData('<rootNode />').DocumentElement.AddChild('someChildNode'); end; // hier alles automatisch weg procedure myProc; begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try doXMLStuff; finally CoUninitialize; end; end; |
AW: Kann ich das IntfClear vorziehen?
Warum machst du das eigentlich so?
Rufst du die procedure doXmlStuff() im Main-Thread auf oder in einen eigenen Thread? Für MainThread: Projektdatei ->
Delphi-Quellcode:
In einen eigenen Thread würde ich die Co...-Funktionen im jeweiligen Create und Destroy rufen.
begin
System.Win.ComObj.CoInitFlags := COINIT_APARTMENTTHREADED; Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TKrims, Krams); Application.Run; end. |
AW: Kann ich das IntfClear vorziehen?
Hm, ich kannte es nur so.
So mache ich das immer in Konsolenanwendungen oder Neben-Threads. Das
Delphi-Quellcode:
sehe ich grade zum ersten mal. Man entdeckt immer wieder neues :party:
System.Win.ComObj
Zitat:
(Wenn wir abschweifen bitte ich um Vergebung und den Hinweis darauf) |
AW: Kann ich das IntfClear vorziehen?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz