Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Word-AddIn - Absturz bei OnBeginShutdown (https://www.delphipraxis.net/84650-word-addin-absturz-bei-onbeginshutdown.html)

mjenke 19. Jan 2007 15:00


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:
  TXConMag = class(TOfficeAddIn, IDTExtensibility2, IXConMag)
    private
      FDebug: Boolean;
      [...]
    protected
      procedure OnStartupComplete(var custom: PSafeArray); override; safecall;
      procedure OnBeginShutdown(var custom: PSafeArray); override; safecall;
      [...]
  end;
Implementierung:
Delphi-Quellcode:
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;
Unter WindowsXP wird sie aufgerufen, unter Windows2000 nicht. Dieser Aufruf funktioniert schon gar nicht erst.

Kennt jemand dieses Problem?

:?:
Matthias

shmia 19. Jan 2007 17:27

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:
XConLog.Destroy; // Falsch
XConLog.Free;   // Richtig! die Methode Free ruft intern Destroy auf
Also Suche nach ".Destroy;" -> ersetzen durch ".Free;"

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:
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);
Würden diese Freigaben der Unterobjekt im Destruktor stattfinden, dann würde FGlobalConf.Free ausreichen,
da keine Gefahr mehr besteht, dass mit FGlobalConf noch irgenetwas passiert.

mjenke 22. Jan 2007 08:25

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:
Result := FWord^.ActiveDocument <> nil;
Inzwischen habe ich die Exception abgefangen und alles läuft wie es soll...


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

shmia 22. Jan 2007 09:21

Re: Word-AddIn - Absturz bei OnBeginShutdown
 
Zitat:

Zitat von mjenke
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!

Dann hast du es noch nicht ganz 100% verstanden. :zwinker:
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 10:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz