![]() |
Applikation initialisert "falsche" Unit
Hintergrund:
D7 und Jedi Debug (aus "JVCL345CompleteJCL231-Build4197") - Windows als Ziel OS Datenbankanbindung (via SqlExpr an Firebird DB) Ich suche nun schon geraume Zeit nach einem Problem - folgender Rahmen: wir haben hier eine Anwendung im Bereich Fertigungssteuerung/Planung. Sie ist in mehrere Applikationen aufteilt. Es gibt eine Exe als GUI für den Werkstattbereich und eine zweite Exe für die Arbeitsvorbereitung und Stammdatenpflege (AV). Naturgemäß sind viel Units in beiden Anwendungen eingebunden. Das war bisher kein Problem. Seit einer Woche (nach irgendeiner Änderung von mir, die ich nicht erkenne/finde) habe ich nun das Problem, das beim Start des Werkstattmoduls zuallererst das Hauptformular des AV-Modul initialisiert wird. Die DPR des Werkstattmodul sieht so aus:
Delphi-Quellcode:
Nun wird jedoch vor bzw. bei Application.Initialize das initialization der Unit uMain (das ist das Hauptformular des AV-Moduls) aufgerufen. Das sieht so aus:
program RMWerk;
{%File '..\Tools\FastMM\FastMM4Options.inc'} uses FastMM4 in '..\Tools\FastMM\FastMM4.pas', FastMM4Messages in '..\Tools\FastMM\FastMM4Messages.pas', RtlVclOptimize in '..\Tools\RtlVclOptimize\RtlVclOptimize.pas', MidasSpeedFix in '..\Tools\MidasSpeedFix\MidasSpeedFix.pas', Forms, uMainWerk in 'uMainWerk.pas' {frmMainWerk}, dlg_LAGAusw in 'dlg_LAGAusw.pas' {frmWahlLAG}, Dlg_LogFile in 'Dlg_LogFile.pas' {frmDlgLogFile}, Dlg_StartBuchung in 'Dlg_StartBuchung.pas' {frmDlgStartBuchung}, Dlg_StopBuchung in 'Dlg_StopBuchung.pas' {frmDlgStopBuchung}, dm_Buchung in 'dm_Buchung.pas' {dmBuchung: TDataModule}, dm_Werk in 'dm_Werk.pas' {dmWerk: TDataModule}, uWerkGlob in 'uWerkGlob.pas', Dm_Connection in '..\Prog\Dm_Connection.pas' {DmConnection: TDataModule}, RMGlobFunc in '..\Tools\RMGlobFunc.pas', uRMIni in '..\Prog\uRMIni.pas', RMGlob in '..\Tools\RMGlob.pas', Dm_GlobData in '..\Prog\Dm_GlobData.pas' {DmGlobData: TDataModule}, ufrmUrRM in '..\Prog\ufrmUrRM.pas' {frmUrRM}, RMErrorTool in '..\Tools\RMErrorTool.pas', uRM_JEDI_ExceptionDialog in '..\Prog\uRM_JEDI_ExceptionDialog.pas' {ExceptionDialog}, ufrmRMPasBugReport in '..\Prog\ufrmRMPasBugReport.pas' {frmRMPasBugReport}, uRMMeldungsDialog in '..\Tools\uRMMeldungsDialog.pas' {RMMeldungsDialog}, ufrmRMPKzuFAPAGZuordnung in '..\Prog\ufrmRMPKzuFAPAGZuordnung.pas' {frmRMPKzuFAPAGZuordnung}, RMFormTool in '..\Tools\RMFormTool.pas' {dmRMFormTool: TDataModule}, RMContainer in '..\Prog\RMContainer.pas', uallProcess in '..\Tools\uallTools\uallProcess.pas', uallDisasm in '..\Tools\uallTools\uallDisasm.pas', uallDisasmEx in '..\Tools\uallTools\uallDisasmEx.pas', uallHook in '..\Tools\uallTools\uallHook.pas', uallKernel in '..\Tools\uallTools\uallKernel.pas', uallProtect in '..\Tools\uallTools\uallProtect.pas', uallTableHook in '..\Tools\uallTools\uallTableHook.pas', uallUtil in '..\Tools\uallTools\uallUtil.pas', Dm_dokumente in '..\Tools\Dm_dokumente.pas' {dmDokumente: TDataModule}, RMPAS_FastMMUsageTracker in '..\Tools\FastMM\RMPAS_FastMMUsageTracker.pas' {fFastMMUsageTracker}, ufrmRMInfoPPBaumVergleich in '..\Prog\ufrmRMInfoPPBaumVergleich.pas' {frmRMInfoPPBaumVergleich}, RTTIUnit in '..\Tools\RTTI\RTTIUnit.pas', Dm_RMTV_Menu in '..\Prog\Dm_RMTV_Menu.pas' {DMTV_Menu: TDataModule}, dm_AutoLogin in '..\Tools\dm_AutoLogin.pas' {dmAutoLogin: TDataModule}, DM_GefaehrdungsVerwaltung in '..\Prog\DM_GefaehrdungsVerwaltung.pas' {DMGefaehrdungsVerwaltung: TDataModule}, Dm_RMSB_Menu in '..\Prog\Dm_RMSB_Menu.pas' {DMRMSB_Menu: TDataModule}, ufrmRMStammGefAVPlazet in '..\Prog\ufrmRMStammGefAVPlazet.pas' {frmRMStammGefAVPlazet}, VCLFixes in '..\Tools\VCLFixes.pas'; {$R *.res} {$R ..\Tools\WindowsXP.RES} begin Application.Initialize; Application.Title := 'PASwerk'; Application.CreateForm(TfrmMainWerk, frmMainWerk); Application.Run; end.
Delphi-Quellcode:
Der Aufruf von
initialization
if not JclHookExceptions then MessageDlg('Fehler beim Initialisieren der Exception-Behandlung', mtError, [mbOK], 0); // Enable raw mode (default mode uses stack frames which aren't always generated by the compiler) Include(JclStackTrackingOptions, stRawMode); // Disable stack tracking in dynamically loaded modules (it makes stack tracking code a bit faster) Include(JclStackTrackingOptions, stStaticModuleList); Include(JclStackTrackingOptions, stTraceAllExceptions); // Initialize Exception tracking if (not JclStartExceptionTracking) then MessageDlg('Fehler beim Instanzieren des Exception-Tracking (Fehlerverfolgung)!', mtWarning, [mbOK], 0);; OleInitialize(nil);
Delphi-Quellcode:
liefert ein "False" - klar, es ist ja auch das Werkstattmodul gestartet.
JclStartExceptionTracking
Meine Frage nun: kann mir jemand einen Tipp geben, WARUM das inizialization der Unit uMain (AV-Modul) überhaupt bei Application.Initialize im Werkstatt-Modul aufgerufen wird? Nach meinem Verständnis dürfte dies gar nicht aufgerufen werden. Die Unit uMain ist NICHT im uses - es existiert lediglich eine indirekte Abhängigkeit, die bisher nie zum o.g. Problem führt. Ich hoffe, meine verwirrten Gedanken haben eine einirgmaßen verständliche Situationsbeschreibung erlaubt .. |
AW: Applikation initialisert "falsche" Unit
Vielleicht wäre noch uMainWerk.pas interessant. Bzw. die Unit in welcher im Initialsierungteil ggf. auf die andere Unit zugegriffen wird.
|
AW: Applikation initialisert "falsche" Unit
das sind recht große Units und viel Code drumrum - ich habe mal die uses rausgezogen, vielleicht hilft das schon.
Also die uses von uMainWerk bis zum type:
Delphi-Quellcode:
und hier das gleiche von uMain:
unit uMainWerk;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, ComCtrls, ExtCtrls, ActnList, StdCtrls, Menus, Provider, DB, DBClient, Grids, DBGrids, Mask, DBCtrls, ToolWin, ImgList, SQLTimSt, DateUtils, dm_AutoLogin, uWerkGlob, RMSQLDataSet, ufrmUrRM, //FormRoller, DM_GlobData, //JvComponentBase, JvExControls, JvXPCore, JvXPButtons, JvSpeedButton JvComponentBase, JvCaptionButton, JvExControls, JvXPCore, JvXPButtons, JvExExtCtrls, JvExtComponent, JvXPCheckCtrls, JvSpeedButton, RMContainer, uIntList, l14, cmbtll14, cmbtls14, ZodPageControl, ZodDBGrid, RMGlob, uRMObjects, Dm_RMTV_Menu, Dm_RMSB_Menu, JvExDBGrids, JvDBGrid, JvDBUltimGrid, JvLabel, FMTBcd, SqlExpr, TB2Item, TB2Dock, TB2Toolbar, JvImage, JvExStdCtrls, JvMemo, TB2ToolWindow, AppEvnts ; const CON_MENGENTYP_PP = 0; CON_MENGENTYP_QC = 1; CON_MENGENTYP_KEINE = 2; CON_NAMEPREFIX_PPINFOTV_TOOLBAR = 'TBToolbarPPInfoLAG'; CON_NAMEPREFIX_PPINFOTV_TOOLWINDOW = 'TBToolWindowPPInfoLAG'; CON_NAMEPREFIX_PPINFOTV_MEMZEITSTEMPEL = 'MemZeitStempelPPInfoLAG'; CON_MITPPINFOANZEIGE = FALSE; CON_MITPPVERGLEICH = FALSE; CON_UMAINWERK_STATUSBAR_PANELNO_PROGVERSION = 0; CON_UMAINWERK_STATUSBAR_PANELNO_DATUM = 1; CON_UMAINWERK_STATUSBAR_PANELNO_GEF = 2; CON_UMAINWERK_STATUSBAR_PANELNO_QM_STATISTIK = 3; CON_UMAINWERK_STATUSBAR_PANELNO_BENUTZER = 4; type TfrmMainWerk = class(TfrmUrRM)
Delphi-Quellcode:
Die indirekte Abhängigkeit zu uMain ist in zwei Units gegeben: RMGlobFunc und uRMIni
unit uMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, ActnList, ImgList, ToolWin, Menus, FMTBcd, DB, SqlExpr, RMGlob, dm_MakeTree, uRMObjects, ufrmUrRM, Fortschr, RMSQLDataSet, RMBasisObject, sdl_SDLColors, ShellApi, CorEdit, mylabel, ActiveX, ShlObj, ComObj, Provider, DBClient, Buttons, Dm_GlobData, Dm_RMTV_Menu, AppEvnts, JvComponentBase, JvCaptionButton, JvExControls, JvXPCore, JvXPButtons, JvExExtCtrls, JvExtComponent, JvClock, JvXPCheckCtrls, DragDrop, DropSource, DragDropFile, OleCtrls, PdfLib_TLB, DM_Connection_MLaunch, JvExComCtrls, JvCoolBar, TB2Item, TB2Dock, TB2Toolbar, TB2ExtItems, TB2ToolWindow, JvComCtrls, JvCheckTreeView, Grids, DBGrids, JvExDBGrids, JvDBGrid, JvDBUltimGrid, ZodPageControl, ZodDBGrid, uRMPopupListEx, VirtualTrees, JvLabel ; const CON_UMAIN_STATUSBAR_PANELNO_BENUTZER = 0; CON_UMAIN_STATUSBAR_PANELNO_LOGIN = 1; CON_UMAIN_STATUSBAR_PANELNO_SUPERVISOR = 2; CON_UMAIN_STATUSBAR_PANELNO_GEF = 3; CON_UMAIN_STATUSBAR_PANELNO_QM_STATISTIK = 4; CON_UMAIN_STATUSBAR_PANELNO_NODE_STATUS = 5; CON_UMAIN_STATUSBAR_PANELNO_NODE_ICON = 6; CON_UMAIN_STATUSBAR_PANELNO_NODE_TEXT = 7; CON_UMAIN_STATUSBAR_PANELNO_STATUSINFO = 8; type TfrmMain = class(TfrmUrRM, IDropSource) Hier die uses von RMGolbFunc:
Delphi-Quellcode:
und hier die uses aus dem Vorgänger RMGlobFuncUniversal:
unit RMGlobFunc;
interface uses classes, SysUtils, Forms, Controls, ShellAPI, StrUtils, Graphics, sdl_SDLColors, uIntList, CheckLst, MAPI, StdCtrls, ActiveX, ShlObj, ComObj, ComCtrls, JvComponentBase, JvCaptionButton, JvExControls, JvXPCore, JvXPButtons, JvExExtCtrls, JvExtComponent, JvXPCheckCtrls, JvSpeedButton, RMSQLDataSet,Types, Menus, ActnList, Printers, DBClient, DB, DBGrids, JPEG, WinSock, Grids, ExtCtrls, CorEdit, TB2Item, TB2Toolbar, RMBasisObject, uRMObjects, uRMPing, uRMPingDialog, RMGlob, RMGlobFuncUniversal, l14 ; type TRMGlobFuncException = class(TRMGlobFuncUniversalException); type TRMGlobFunc = class(TRMGlobFuncUniversal)
Delphi-Quellcode:
und last but not least die uses von RMGlobFUncBasis
unit RMGlobFuncUniversal;
interface uses RMGlob, classes, SysUtils, Forms, Controls, ShellAPI, StrUtils, Graphics, sdl_SDLColors, uIntList, CheckLst, MAPI, StdCtrls, ActiveX, ShlObj, ComObj, ComCtrls, Types, Menus, ActnList, Printers, DBClient, DB, DBGrids, JPEG, WinSock, Grids, ExtCtrls, CorEdit, RMGlobFuncBasis, Windows, Contnrs //RMSQLDataSet, //JvComponentBase, //JvCaptionButton, JvExControls, JvXPCore, JvXPButtons, //JvExExtCtrls, JvExtComponent, JvXPCheckCtrls, JvSpeedButton, //TB2Item, TB2Toolbar ; type TRMGlobFuncUniversalException = class(TRMGlobFuncBasisException); // Für Registrierung TDllRegisterServer = function: HResult; stdcall; // für die Dateiausführung TExecuteWaitEvent = procedure(const ProcessInfo: TProcessInformation; var ATerminate: Boolean) of object; type TRMGlobFuncUniversal = class(TRMGlobFuncBasis)
Delphi-Quellcode:
Die uses der Unit uRMIni sieht so aus (Konstantendefinitionen gekürzt):
uses
classes, SysUtils, Forms ; type TRMGlobFuncBasisException = class(Exception); // Für Registrierung TRMGlobFuncBasis = class(TComponent)
Delphi-Quellcode:
unit uRMIni;
interface uses SysUtils, Classes, FMTBcd, DBClient, Provider, DB, SqlExpr, DBXpress, Controls, IniFiles, StrUtils, Dialogs, Forms, uIntList, RMGlob ; const . . . type //---------------------------------------------------------------------------- // Fehlerklasse für Fehler innerhalb des Ini Tools //---------------------------------------------------------------------------- TRMIniException = class(Exception); //---------------------------------------------------------------------------- // INI-Tool zum Ermitteln von Informationen aus der globalen INI-Datei //---------------------------------------------------------------------------- TRMIni = class(TIniFile) |
AW: Applikation initialisert "falsche" Unit
Moin ZOD,
gerade bei einem komplexen Projekt durfte es ziemlich aussichtslos sein die Reihenfolge in der die Initialization-Abschnitte ausgeführt werden von Hand zu ermitteln. Das entnehme ich zumindest den Ausführungen, die Hagen ![]() Vielleicht hilft es Dir weiter. |
AW: Applikation initialisert "falsche" Unit
zur Vollständigkeit noch die uses von DmGlobData:
Delphi-Quellcode:
und RMGlob:
unit
Dm_GlobData; interface uses SysUtils, Classes, Dialogs, ImgList, Controls, JvComponentBase, JvXPCore, ExtCtrls, RMGlob, Graphics, StrTools, JvInterpreter, JvInterpreterFm, FMTBcd, DB, DBClient, Provider, SqlExpr, RMSQLDataSet; type //---------------------------------------------------------------------------- // Fehlerklasse für Fehler innerhalb der Unit //---------------------------------------------------------------------------- TDMGlobDataException = class(Exception); TDmGlobData = class(TDataModule)
Delphi-Quellcode:
und ufrmUrRM:
unit RMGlob;
interface uses SysUtils, Messages, types, classes, Forms, controls, Dialogs, ComCtrls, Graphics, sdl_SDLColors, StdCtrls, DateUtils, Contnrs, VirtualTrees ; type
Delphi-Quellcode:
unit ufrmUrRM;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, RMGlob, Printers, Math, ExtCtrls, StdCtrls, DBXpress, JvComponentBase, JvCaptionButton, ActnList, JvExExtCtrls, JvExtComponent, JvExControls, JvXPCore, JvXPButtons, DM_GlobData, DBGrids, ZodDBGrid ; const CON_UrRM_BLANKS_FUER_CAPTION_CAPTIONBUTTON = ' '; type TfrmUrRM = class(TForm) |
AW: Applikation initialisert "falsche" Unit
Zitat:
Ah und in System.InitUnits werden die Units durchgegangen und ein Initialization aufgerufen - das wäre sogar der bessere Ort für die Anlayse, dann bekommst Du auch die units die kein FOrmular haben.... sollte dort ein Verweis auf das Hauptformular stehen.... |
AW: Applikation initialisert "falsche" Unit
Sagen wir mal so:
Durch die Uses-Listen wissen wir jetzt, wo was gebraucht werden könnte. Prinzipiell kann man in die Uses-Liste alle Units einfügen, die man so kennt oder auf der Platte hat. Dies bedeutet nicht, dass aus diesen Units irgendwo, irgendwas "gebraucht" wird. Soweit ich das mitbekommen habe, baut Delphi beim Kompilieren letztlich aber nur das zusammen, was auch gebraucht wird. Der Initialisierungsteil einer nicht benötigten Unit wird daher nicht in die Exe übernommen. (Falls diese Aussage falsch ist, bitte hauen, damit ich mein Halbwissen aufbessern kann.) Momentan gehe ich davon aus, dass aus der Unit, deren Initialisierungsteil "unerwartet früh" aufgerufen wird, schon irgendwo etwas benötigt wird, bevor die Unit uMainWerk.pas "irgendwie" angepackt wird. Welche konkrete Verbindung besteht zwischen der Unit uMainWerk.pas und der "zu früh" initialisierten? Wird da irgendwo im FormCreate schon was aufgerufen? Mein Vorgehen wäre hier folgendes: Es muss eine Loggingfunktion (in 'ner Komponente oder so), die in jede projektspezifische Unit eingebunden wird, vorhanden sein. Alle Loggingeinträge "landen" in einer Datei. Vor dem Schreiben des Eintrages wird die Datei geöffnet, nach dem Schreiben geschlossen. In jeder projektspezifischen Unit wird im Initialisierungsbereich eine Zeile mit einem Zeitstempel und dem Namen der Unit in die Logdatei geschrieben. Hiermit sollte anschließend die Aufrufreihenfolge der projektspezifischen Units "schriftlich" vorliegen. Mit diesem Wissen kann man dann etwas gezielter die Abhängigkeiten durchforsten. Prinzipiell hat man ja in jeder Unit zwei Uses-Blöcke, einen im Interface, den zweiten unter Implementation. Alle Units, die nicht bereits zwingend im Interface bekannt sein müssen, da dort noch keine Abhängigkeiten bestehen, gehören in die Uses-Anweisung unter Implementation, auch dann, wenn Delphi sie automatisch in die Uses-Anweisung des Interface gepackt hat. Soweit ich das mitbekommen habe, scheint dies auch Auswirkungen auf die Reihenfolge des Ladens der Units zu haben, lasse mich aber gerne eines Besseren belehren, da ich mich mit den Interna nun wirklich nicht so besonders auskenne. |
AW: Applikation initialisert "falsche" Unit
hallo,
also wenn ich das Problem richtig verstehe, kann ich als Programmierer keine Aussage darüber treffen, in welcher Reihenfolge die initalizion Blöcke ausgeführt werden. Sobald ich eine Unit (auch über drei Ecke einbinde) wird der Block irgendwann ausgeführt. Wenn ich aber keine Aussage treffen kann, wann der Block aufgerufen wird, muss ich diesen Block eben so programmieren, dass es immer funktioniert. mfg |
AW: Applikation initialisert "falsche" Unit
Danke für die Antworten bisher.
Während der Zuführung von Eiweisen und Kohlehydraten habe ich folgenden Gedanken entwickelt: Was wäre, wenn die initialization von uMain schon immer aufgerufen wurden, nur dass bisher einfach die Funktion
Delphi-Quellcode:
True zurückgeliefert hat?
JclStartExceptionTracking
Dann wäre die Frage - was passiert in
Delphi-Quellcode:
oder besser: was fehlt, damit dort ein True als Rückgabewert gemeldet wird?
JclStartExceptionTracking
|
AW: Applikation initialisert "falsche" Unit
Das kannst Du hier jcl\source\windows\JclDebug.pas nachschauen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 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 by Thomas Breitkreuz