AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Globale Exceptions abfangen?

Ein Thema von DelphiPeter · begonnen am 7. Nov 2009 · letzter Beitrag vom 8. Nov 2009
Antwort Antwort
DelphiPeter

Registriert seit: 21. Dez 2007
Ort: Iserlohn
198 Beiträge
 
Delphi 2010 Professional
 
#1

Globale Exceptions abfangen?

  Alt 7. Nov 2009, 14:26
Hi Leute, ich habe in eine Prozedur, die globale Exceptions abfangen soll, in einer DLL ausgelagert. Schön mit Formular, Screenshot machen und Bugreport versenden, wie man das eben so kennt.

Nun wollte ich das so, in meiner Demo Anwendung anwenden, was aber nicht funktioniert:

Delphi-Quellcode:
...
  procedure AppException(Sender: TObject; E: Exception); stdcall; external 'toexc.dll';
...
  Application.OnException := AppException;
...
Die DLL Prozedur sieht so aus..

Delphi-Quellcode:
...
procedure AppException(Sender: TObject; E: Exception); stdcall;
begin
  {...}
end;

exports AppExecption;
...
Der Compiler sagt mir beim erzeugen der DEMO Anwendung:

Zitat:
[DCC Fehler] Unit1.pas(40): E2009 Inkompatible Typen: 'Unterschiede in der Aufrufkonvention'
Was habe ich denn nun nicht bedacht?
Peter Majewski
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Globale Exceptions abfangen?

  Alt 7. Nov 2009, 14:33
Wie kommst du auf die Idee, dass das stdcall sein sollte? Außerdem kannst du eine normale Routine nicht verwenden, du brauchst eine Methode.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Globale Exceptions abfangen?

  Alt 7. Nov 2009, 14:36
Zitat von Apollonius:
Außerdem kannst du eine normale Routine nicht verwenden, du brauchst eine Methode.
Naja doch, wenn er in der Anwendung den Exception-Handler normal definiert und dort drin die DLL-Methode aufruft (die Parameter sozusagen weiterreicht)

@DelphiPeter: Du musst höllisch aufpassen, da die DLL ihre eigene VCL mit reinverlinkt, und das furchtbar krachen kann (insb. wenn die DLL mit einer anderen Delphi Version erstellt wurde) -- du könntest Dir überlegen BPLs zu verwenden
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
DelphiPeter

Registriert seit: 21. Dez 2007
Ort: Iserlohn
198 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Globale Exceptions abfangen?

  Alt 7. Nov 2009, 14:38
öhm, ich habe Prozeduren bis dato immer als stdcall aus einer DLL exportiert ?

Zitat:
Du musst höllisch aufpassen, da die DLL ihre eigene VCL mit reinverlinkt, und das furchtbar krachen kann (insb. wenn die DLL mit einer Delphi Version erstellt wurde) -- du könntest Dir überlegen BPLs zu verwenden
So, BPLs klingen da irgendwie besser. Wie gehe ich das am besten an?
Peter Majewski
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Globale Exceptions abfangen?

  Alt 7. Nov 2009, 14:42
Zitat von DelphiPeter:
öhm, ich habe Prozeduren bis dato immer als stdcall aus einer DLL exportiert ?
Muss aber auf beiden Seiten konsistent sein -- wenn Du in Delphi nichts dazuschreibst, hast Du automatisch "register" als Aufrufkonvention und mit stdcall zusammen passt des nicht

Zitat:
Zitat:
Du musst höllisch aufpassen, da die DLL ihre eigene VCL mit reinverlinkt, und das furchtbar krachen kann (insb. wenn die DLL mit einer Delphi Version erstellt wurde) -- du könntest Dir überlegen BPLs zu verwenden
So, BPLs klingen da irgendwie besser. Wie gehe ich das am besten an?
Die einfache Variante ist deine Anwendung mit Laufzeitpackages zu compilieren (siehe Projektoptionen).

Deinen zusätzlichen Code nimmst Du in eines Projekt "Package" und compilierst dieses Package. Den Namen des letzteren bindest Du dann in die Liste der Laufzeitpackages in den Optionen der Hauptanwendung ein.

Beachte: Du musst in dieser Variante alle VCL-BPLs auch mit dazuliefern (neben Deiner eigenen), wenn Du Deine Anwendung weitergibst.

Das ganze noch weitergehend zu erklären, würde denke ich den Rahmen dieses Posts sprechen. Such am besten nach Tutorials, wo die Möglichkeiten genauer erklärt und beschrieben werden.
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#6

Re: Globale Exceptions abfangen?

  Alt 8. Nov 2009, 00:07
Da wie bei vielen/allen Klassen die Typen/Klassen nhand iher "Zeiger" unterschieden werden, ist so eine korrekte Exceptions Auswertung garnicht richtig möglich.

Da eine Exception in der VCL der EXE in der DLL rein abstammungstechnisch nicht von der Exceptions-Basisklasse der DLL abstammen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

Re: Globale Exceptions abfangen?

  Alt 8. Nov 2009, 12:47
Da ich die Idee gar nicht mal so abwegig finde, habe ich das mal rudimentär so umgesetzt, wie ich mir das vorstelle

- Die AppExceptions werden nur umgebogen, wenn die DLL auch vorhanden ist
- Das Umbiegen erfolgt automatisch durch das Einbinden einer Unit
- In dieser Unit wird die Exception in die relevanten Einzelteile zerlegt und der DLL zugeführt

Hier die Unit zum Einbinden:
Delphi-Quellcode:
unit uAppExceptionHandlerClass;

// Dieses ist die Verbindung zwischen dem Delphi-Programm und der DLL

interface

uses
  Windows, SysUtils;

type
  TAppException = procedure( ParentForm, Sender : Pointer; lExeName, lMessage,
    lStackTrace : PChar; HelpContext : integer );

type
  TAppExceptionHandlerClass = class
  private
    FDLLHandle : cardinal;
    procedure SetDLLHandle( const Value : cardinal );
    function GetFarProc( const FarProcName : string; var FarProc : TFarProc )
      : boolean;

  public
    property DLLHandle : cardinal read FDLLHandle write SetDLLHandle;
    procedure AppExceptionHandler( Sender : TObject; E : Exception );
    function LoadDLL : boolean;
    function UnloadDLL : boolean;
  end;

var
  FAppExceptionHandler : TAppExceptionHandlerClass;

implementation

uses
  Dialogs, Forms;

const
  AppExceptionHandlerDLLName = 'insaexhd.dll';

procedure BindDLL;
  var
    proc : TFarProc;
  begin
    with FAppExceptionHandler do
      if LoadDLL then
        if GetFarProc( 'AppException', proc ) then
          Application.OnException := AppExceptionHandler;
  end;

procedure UnbindDLL;
  begin
    with FAppExceptionHandler do
      if not UnloadDLL then
        ShowMessage( 'DLL konnte nicht entladen werden!' );
  end;

{ TAppExceptionHandlerClass }

procedure TAppExceptionHandlerClass.AppExceptionHandler
  ( Sender : TObject; E : Exception );
  var
    proc : TFarProc;
  begin
    if GetFarProc( 'AppException', proc ) then
      TAppException( proc )( Application.MainForm, Sender, PChar
          ( Application.ExeName ), PChar( E.Message ), PChar( E.StackTrace ),
        E.HelpContext );
  end;

function TAppExceptionHandlerClass.GetFarProc( const FarProcName : string;
  var FarProc : TFarProc ) : boolean;
  begin
    if LoadDLL then
      FarProc := GetProcAddress( DLLHandle, PChar( FarProcName ) )
    else
      FarProc := nil;
    RESULT := Assigned( FarProc );
  end;

function TAppExceptionHandlerClass.LoadDLL : boolean;
  begin
    if ( DLLHandle = 0 ) then
      DLLHandle := LoadLibrary( PChar( AppExceptionHandlerDLLName ) );
    RESULT := ( DLLHandle <> 0 );
  end;

procedure TAppExceptionHandlerClass.SetDLLHandle( const Value : cardinal );
  begin
    FDLLHandle := Value;
  end;

function TAppExceptionHandlerClass.UnloadDLL : boolean;
  begin
    if ( DLLHandle <> 0 ) then
      if FreeLibrary( DLLHandle ) then
        DLLHandle := 0;
    RESULT := ( DLLHandle = 0 );
  end;

initialization

FAppExceptionHandler := TAppExceptionHandlerClass.Create;
BindDLL;

finalization

UnbindDLL;
FreeAndNil( FAppExceptionHandler );

end.
Die DLL im Anhang ist mit D2010 compiliert, somit sind die Parameter vom Typ PWideChar!
Dieses sollte/müsste in dem Projekt noch berücksichtigt werden, damit eine DLL auch
universell einsetzbar ist.

cu

Oliver
Angehängte Dateien
Dateityp: zip appexceptionhandler_124.zip (761,9 KB, 23x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:58 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