Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wert aus Klasse nicht verfügbar (https://www.delphipraxis.net/145042-wert-aus-klasse-nicht-verfuegbar.html)

Ruio 22. Dez 2009 14:40


Wert aus Klasse nicht verfügbar
 
Ich logge in meinem Programm vieles.
Nun gibts es bei an einer Bestimmten Stelle ein Problem damit.
Stelle:
Delphi-Quellcode:
procedure Tt4rCore.ReceiveAppMessage(var Msg: TWMCopyData);
var
  sText: array[0..999999] of Char;
  SenderAndAction,Action,Sender: String;
begin
  SenderAndAction := '0000'+IntToStr(Msg.CopyDataStruct.dwData);
  Log(SenderAndAction,T4R_LOGLEVEL_INFOS);
  Action := Copy(SenderAndAction,Length(SenderAndAction)-3,2);
  Sender := Copy(SenderAndAction,0,Length(SenderAndAction)-3);
  StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
  ReceiveAppMessageCallback(Sender,Action, sText);
end;
Der Debugger zeigt eine AV bei dem hier an:
Delphi-Quellcode:
if (Loglevel<=FErrorLogLevel) then
  ErrorLogWrite(LogFlag, Msg);
FErrorLogLevel wird am Anfang gleich festgelegt und sollte verfügbar sein. Beim weiteren Nachforschen habe ich festgestellt, dass der Debugger bei FErrorLogLevel WErt nicht verfügbar anzeigt.

fkerber 22. Dez 2009 14:42

Re: Wert aus Klasse nicht verfügbar
 
Hi!

Kann es sein, dass die Stelle, wo du sagst, dass da ne AV kommt, nicht in dem Code-Abschnitt ist, den du obendrüber zeigst?


Grüße, Frederic

hugo1990 22. Dez 2009 15:14

Re: Wert aus Klasse nicht verfügbar
 
Ich würde mal behaupten, ohne den kompletten Quellcode zu kennen, dass du einfach vergessen hast, das entsprechende Objekt (das Objekt welches FErrorLogLevel beinhaltet) zu erzeugen, bevor du drauf zu greifst.

Ruio 22. Dez 2009 15:43

Re: Wert aus Klasse nicht verfügbar
 
FErrorLogLevel gehört zu Tt4rCore.

Und der Rest zu dem Codeausschnitt:
Delphi-Quellcode:
procedure Tt4rCore.Log(Msg: String; Loglevel: Integer);
var LogFlag: String;
begin
  LogFlag := T4R_FLAG_ERROR;
  case Loglevel of
    T4R_LOGLEVEL_ERRORS: LogFlag := T4R_FLAG_ERROR;
    T4R_LOGLEVEL_INFOS: LogFlag := T4R_FLAG_INFO;
  end;
  if (Loglevel<=FErrorLogLevel) then
  ErrorLogWrite(LogFlag, Msg);
end;

sx2008 22. Dez 2009 15:53

Re: Wert aus Klasse nicht verfügbar
 
Zitat:

Zitat von Ruio
Delphi-Quellcode:
procedure Tt4rCore.ReceiveAppMessage(var Msg: TWMCopyData);
var
  sText: array[0..999999] of Char; // <= !!!

Willst du wirklich annähernd 1 MB vom Stack verwenden?
(das kann zu Stackoverflow führen)
Du solltest sText besser dynamisch reservieren.

hugo1990 22. Dez 2009 15:59

Re: Wert aus Klasse nicht verfügbar
 
Also wenn die Zugriffsverletzung wirklich an dieser Stelle auftrit, dann kann das Objekt einfach nicht richtig erzeugt worden sein. Da es sich ja bei FErrorLogLevel um nen Integer handelt und man bei nem Zugriff darauf sonst keine Zugriffsverletzung bekommt.

mkinzler 22. Dez 2009 16:00

Re: Wert aus Klasse nicht verfügbar
 
Zeig mal die Erzeugung des Objektes

Ruio 22. Dez 2009 16:37

Re: Wert aus Klasse nicht verfügbar
 
Die Log-Funktion geht sonst aber, die AV wird nämlich geloggt.
Delphi-Quellcode:
constructor Tt4rCore.Create(AppName : String);
begin
  inherited Create;
//...
  //Errorlog
  ForceDirectories(Ft4rAppDataPath+T4R_LOGFOLDER_NAME+'\');
  FErrorLogFile := Ft4rAppDataPath+T4R_LOGFOLDER_NAME+'\'+FAppName+'.txt';    
  FErrorLogLevel := GetIniValue(T4R_INI_SECTION_MAIN, T4R_INI_SETTING_LOGLEVEL, T4R_INI_SETTING_LOGLEVEL_DEFAULT);
  FErrorLogActive := true;
  Application.OnException := AppException;
end;

procedure Tt4rCore.AppException(Sender: TObject; E: Exception);
begin
  try
    if FErrorLogActive then
      ErrorLogWrite(T4R_FLAG_ERROR, '('+E.ClassName+') '+E.Message + ' (Error caused by ' + Sender.ClassName + ')');
  finally
    Application.ShowException(E);
  end;
end;

Ruio 23. Dez 2009 11:55

Re: Wert aus Klasse nicht verfügbar
 
Problem gelöst, ich hatte alles im OnCreate, aber da kam scheinbar eine Message zu früh an und deshalb gabs die AV.

Ruio 23. Dez 2009 16:19

Re: Wert aus Klasse nicht verfügbar
 
Der Fehler ist wohl doch nicht da:
Delphi-Quellcode:
procedure Tt4rCore.ReceiveAppMessage(var Msg: TWMCopyData);
var
  sText: array[0..999999] of Char;
  SenderAndAction,Action,Sender: String;
begin
  SenderAndAction := '0000'+IntToStr(Msg.CopyDataStruct.dwData);
  //Log(SenderAndAction,T4R_LOGLEVEL_INFOS);
  Action := Copy(SenderAndAction,Length(SenderAndAction)-3,2);
  Sender := Copy(SenderAndAction,0,Length(SenderAndAction)-3);
  StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
  ReceiveAppMessageCallback(Sender,Action, sText); //Hier wird die AV jetzt angezeigt
end;
Und zu array[0..999999] of Char;
Ein Dynamisches Array ging da nicht und weil ich nocht weiß wie viel da mal versendet wird ist das erstmal 999999 groß.

sx2008 23. Dez 2009 18:10

Re: Wert aus Klasse nicht verfügbar
 
Zitat:

Zitat von Ruio
Und zu array[0..999999] of Char;
Ein Dynamisches Array ging da nicht und weil ich nocht weiß wie viel da mal versendet wird ist das erstmal 999999 groß.

Das geht doch eleganter und resourcensparender mit SetString():
Delphi-Quellcode:
procedure Tt4rCore.ReceiveAppMessage(var Msg: TWMCopyData);
var
  sText: string;
begin
...
  SetString(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); // Daten in String kopieren
  ReceiveAppMessageCallback(Sender,Action, sText);
end;

Ruio 23. Dez 2009 20:19

Re: Wert aus Klasse nicht verfügbar
 
Zitat:

Zitat von sx2008
Zitat:

Zitat von Ruio
Und zu array[0..999999] of Char;
Ein Dynamisches Array ging da nicht und weil ich nocht weiß wie viel da mal versendet wird ist das erstmal 999999 groß.

Das geht doch eleganter und resourcensparender mit SetString():
Delphi-Quellcode:
procedure Tt4rCore.ReceiveAppMessage(var Msg: TWMCopyData);
var
  sText: string;
begin
...
  SetString(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); // Daten in String kopieren
  ReceiveAppMessageCallback(Sender,Action, sText);
end;

Danke!
Das kommt davon, wenn man noch nicht weiß, was der Code überhaupt macht.

Nur leider bleibt die AV:
Zitat:

---------------------------
t4rappdemosatellite
---------------------------
Zugriffsverletzung bei Adresse 00457C53 in Modul 't4rAppDemoSatellite.exe'. Lesen von Adresse 00000000.
---------------------------
OK
---------------------------

Ruio 24. Dez 2009 10:52

Re: Wert aus Klasse nicht verfügbar
 
Ich hängs mal an, vielleicht findet jemand den Fehler.

hugo1990 24. Dez 2009 12:17

Re: Wert aus Klasse nicht verfügbar
 
Ich würds gern testen, aber leider fehlen mir diese beiden Units:
dirs, HTMLColorConversions

Edit:
beim Codeüberfliegen habe ich den Fehler gefunden:

Delphi-Quellcode:
procedure TMainForm.ReceiveAppMessage(var Msg: TWMCopyData);
begin
  t4r.ReceiveAppMessage(Msg);
end;
Du stellst nicht sicher, dass t4r an dieser Stelle bereits erzeugt wurde. Wenn jetzt eine Nachricht empfangen wird, bevor t4r erzeugt wurde, gibt es eine Zugriffsverletzung.

Das hier sollte Abhilfe schaffen:
Delphi-Quellcode:
procedure TMainForm.ReceiveAppMessage(var Msg: TWMCopyData);
begin
  if t4r <> nil then
    t4r.ReceiveAppMessage(Msg);
end;
oder

Delphi-Quellcode:
procedure TMainForm.ReceiveAppMessage(var Msg: TWMCopyData);
begin
  if t4r = nil then
  begin
    t4r := Tt4r.Create(MainForm.Caption);
    t4r.ReceiveAppMessage(Msg);
  end;
end;
Edit2:
Außerdem solltest du das folgende nicht im OnShow sondern im OnCreate aufrufen:
Delphi-Quellcode:
  t4r := Tt4r.Create(MainForm.Caption);
  t4r.InitForm;

Ruio 24. Dez 2009 12:51

Re: Wert aus Klasse nicht verfügbar
 
Zitat:

Zitat von hugo1990
beim Codeüberfliegen habe ich den Fehler gefunden:
[delphi]
Das hier sollte Abhilfe schaffen:
Code:
procedure TMainForm.ReceiveAppMessage(var Msg: TWMCopyData);
begin
  if t4r <> nil then
    t4r.ReceiveAppMessage(Msg);
end;
oder

Code:
procedure TMainForm.ReceiveAppMessage(var Msg: TWMCopyData);
begin
  if t4r = nil then
  begin
    t4r := Tt4r.Create(MainForm.Caption);
    t4r.ReceiveAppMessage(Msg);
  end;
end;

Dann kommen ja die Messages nicht durch bzw. create ichh meine Klasse ja nochmal.
Ich werds ein bisschen umschreiben und nochmal testen.



Edit: Es geht jetzt!
:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:45 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