![]() |
Word-AddIn - Absturz bei OnBeginShutdown
Hallo, alle miteinander!
Ich sitze mal wieder an einem Problem mit meinem Word-AddIn, das mich schon die letzten Wochen beschäftigt. Und zwar passiert folgendes: Word 2003 stürzt ab, wenn man es beendet. (Problembericht kann an Microsoft geschickt werden etc.) Allerdings nur unter Windows2000. Unter WindowsXP läuft alles einwandfrei. In einem Word-AddIn müssen die Methoden der IDExtensibility2-Schnittstelle implementiert sein. Das Problem tritt auf, bei dem Aufruf der zu implementierenden Methode "OnBeginShutdown" Deklaration:
Delphi-Quellcode:
Implementierung:
TXConMag = class(TOfficeAddIn, IDTExtensibility2, IXConMag)
private FDebug: Boolean; [...] protected procedure OnStartupComplete(var custom: PSafeArray); override; safecall; procedure OnBeginShutdown(var custom: PSafeArray); override; safecall; [...] end;
Delphi-Quellcode:
Unter WindowsXP wird sie aufgerufen, unter Windows2000 nicht. Dieser Aufruf funktioniert schon gar nicht erst.
procedure TXConMag.OnBeginShutdown(var custom: PSafeArray);
begin XConLog.Log ( 'TXConMag.OnBeginShutDown' ); // Wenn nötig den Ursprungszustand wieder herstellen... if FDokOptsChangedByConfig then begin try FWordSettings.DokOptions_Write ( FDokOpts ); except end; end; // free the taken resources XConLog.Log ( 'TXConMag.OnBeginShutDown: Destroy Resources' ); FGlobalConf.Destroy; FWordSettings.Destroy; FEnvColl.Destroy; FDokOpts.Destroy; XConLog.Log ( 'TXConMag.OnBeginShutDown: Destroy XConLog' ); XConLog.Destroy; inherited OnBeginShutdown(custom); end; Kennt jemand dieses Problem? :?: Matthias |
Re: Word-AddIn - Absturz bei OnBeginShutdown
Du zerstörst deine ganzen Unterobjekte in OnBeginShutdown. Zu früh!!!
Ich würde das erst im Destruktor Destroy machen, der dann aufgerufen wird, wenn dein Plugin-Objekt wirklich entfernt wird. Das Event gibt dir Gelegenheit um irgendwelche Daten zu speichern oder für eine Rückfrage beim Benutzer. Das Objekt XConLog sollte definitiv erst im Destruktor ge"free"t werden. Ausserdem darf man Destroy nie selbst direkt aufrufen:
Delphi-Quellcode:
Also Suche nach ".Destroy;" -> ersetzen durch ".Free;"
XConLog.Destroy; // Falsch
XConLog.Free; // Richtig! die Methode Free ruft intern Destroy auf Und noch was: Jedes (Unter-)Objekt, dass du mit Free freigibst lässt eine Spur zurück, nämlich die Object-Variable die nun auf einen ungültigen Speicherbereich zeigt:
Delphi-Quellcode:
Würden diese Freigaben der Unterobjekt im Destruktor stattfinden, dann würde FGlobalConf.Free ausreichen,
procedure TXConMag.OnBeginShutdown(var custom: PSafeArray);
begin FGlobalConf.Free; // Unterobjekt freigeben // aber FGlobalConf zeigt jetzt immer noch auf das alte ungültige Objekt // deshalb: FGlobalConf := nil; // jetzt zeigt das Objekt auf nil und kann mit Assigned(FGlobalConf) zumindest geprüft werden // freigeben und auf nil setzen kann man auch in einem Rutsch haben FreeAndNil(FGlobalConf); da keine Gefahr mehr besteht, dass mit FGlobalConf noch irgenetwas passiert. |
Re: Word-AddIn - Absturz bei OnBeginShutdown
Hallo, shmia!
Vielen Dank für die Infos. Hatte letztlich mit dem Problem gar nichts zu tun, da ich feststellen musste, dass ich tatsächlich an einer Stelle im Code eine Exception auslöse, die ich nicht abgefangen habe. WindowsXP ist dabei anscheinend etwas toleranter als Windows2000. Der folgende Code hat die Exception ausgelöst. Die Prüfung, ob Word ein aktives Dokument besitzt.
Delphi-Quellcode:
Inzwischen habe ich die Exception abgefangen und alles läuft wie es soll...
Result := FWord^.ActiveDocument <> nil;
Den Hinweis mit dem FreeAndNil habe ich mir allerdings zu Herzen genommen und die Freigabe der Objekte in den Destruktor meiner Klasse aufgenommen und dies über FreeAndNil realisiert! Danke! :-D Matthias |
Re: Word-AddIn - Absturz bei OnBeginShutdown
Zitat:
FreeAndNil wird dann verwendet, wenn Objekte ausserhalb des Destruktor freigegeben werden und die Gefahr besteht, dass diese Objekt nochmals freigegeben wird oder sonstwie benützt wird. Innerhalb des Destruktor reicht ein einfaches .Free aus, denn danach ist ja das Hauptobjekt zerstört und es werden keine weiteren Methoden ausgerufen. Man kann natürlich überall FreeAndNil verwenden, aber das wäre an vielen Stellen Verschwendung von Rechenzeit. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:03 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