![]() |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Hallo,
ich weiss jetzt nicht ob ich konkret weiterhelfen kann. Was ich bei so Problemen und wenn Konstruktoren oder Destruktoren fehlen mache: leite doch von TIniFile eine neue Klasse ab und verwende diese. Füge der Klasse jeweils ein Create und Destroy hinzu (mit inherited) und setze einen Breakpoint darauf. Manchmal kam es schon vor, dass man schon früher im Destroy vorbei kam als erwartet. Das spätere Free "knallt" dann zu recht. |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Hallo,
Zitat:
steht da wirklich das IniFile.Free? Nun zum Ausklammern: 1. LoadIni: Code komplett ausklammern (erste Zeile ein Exit?) 2. InitSearch: Aufruf von LoadIni ausklammern |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Liste der Anhänge anzeigen (Anzahl: 1)
Ja, in der Zeile 602 steht exakt das :) Ich hab es auch als Screenshot mal anbei mit geschickt.
Also wenn ich den Code ausklammere, dann wird auch kein Fehler kommen. Ich versteh den Sinn an der Stelle nicht so ganz. Ich mein: was ich nicht aufrufe, macht auch keine Probleme, oder? Was soll denn an der Stelle der Nutzen sein, würdest du mir das mal erläutern? |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
1.
Wenn Strings zwischen DLL und Anwendung übergeben werden, muss in beiden ShareMem eingetragen und die "ShareMem.dll" mitgeliefert werden. Alternativ kann man WideString für Parameter und Rückgabewerte verwenden (auch in Records) z.B.
Delphi-Quellcode:
Die Speicherwaltung für diese Strings erfolgt automatich durch OleAuth32, die zu Windows gehört.
function MyFunctionDDL(AParam: WideString): WideString; stdcall;
2. Wenn in der DLL TForm verwendet wird, enthält die DLL eine komplett eigenständige Kopie der VCL. Die VCL verwendet ebenfalls globale Variablen, insbesondere "Application". "Application.Handle" muss vor der Verwendung der VCL in der DLL einmalig gesetzt werden.
Delphi-Quellcode:
3.
{in der DLL, Handle der Anwendung übernehmen}
procedure InitVCL(AHandle: THandle); stdcall; begin Application.Handle := AHandle; end; {in der Anwendung, Handle der Anwendung übergeben} ... InitVCL(Application.Handle); Der Bugreport zeigt, ShowModal wird rekursiv noch einmal aus LoadIni über ProcessMessages aufgerufen. Das ist an sich schon nicht zulässig. Es scheint aber auch das "iniFile" keine lokale Variable der Methode LoadIni ist, wie es eigentlich sein sollte. |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Zitat:
|
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Free prüft selbst ob die Variable bereits nil ist, dann passiert nichts.
Delphi-Quellcode:
TObject(nil).Free; // läuft problemlos
|
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
in Deinem Constructor fehlt ein
Delphi-Quellcode:
sorry .... wurde ja schon angemerkt ....
inherited Create();
|
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Um auf Blup's Post separat zu antworten:
1) Ich übergebe keine Strings. Auch keine WideStrings (auch wenn ich das hier das erste mal lese, aber ist logisch), sondern ich verwende PChar-typen. Das wird ja an unterschiedlichen Stellen so empfohlen, nicht zuletzt im Text des Code-Wizards: Zitat:
3) Ob du es glaubst oder nicht, es IST eine lokale Variable. Ich poste mal den gesamten Code:
Delphi-Quellcode:
Und bei dem "ShowModal" sollte man sich nicht verwirren lassen :) Das muss ich aber glaub genauer erklären. Im Interface zur Dll (Unit-Name "DynamicSearchDialogDllInterface") gibt es eine Methode, die "ShowModal" heißt. Diese wiederum ruft die aus der DLL exportierte Methode "ShowModal" auf (Unit-Name "DynSearchDialog"). Und in dieser Methode wird dann das tatsächliche "ShowModal" des TForm-Objekts aufgerufen (Unit-Name "DynamicSearchDialog"). D.h. ShowModal wird tatsächlich nur einmal aufgerufen, allerdings gibt es davor noch andere Methoden, die halt exakt so heißen. Hat was mit der Integration zu tun, ich wollte halt nicht, dass alle Entwickler ihren Code anpassen müssen, wenn sie auf die DLL umsteigen wollen; oder zumindest nur ganz gering anpassen müssen :P
procedure TFormDynamicSearchDialog.LoadIni;
var iniFile: TIniFile; sec: String; begin if FIniFile <> '' then begin sec := 'Search'; iniFile := nil; try iniFile := TIniFile.Create(FIniFile); miSqlLinkCmdAnd.Checked := iniFile.ReadBool(sec, miSqlLinkCmdAnd.Name, true); miSqlLinkCmdOr.Checked := iniFile.ReadBool(sec, miSqlLinkCmdOr.Name, false); if miSqlLinkCmdAnd.Checked then FSqlLinkCmd := slcAnd else if miSqlLinkCmdOr.Checked then FSqlLinkCmd := slcOr; case iniFile.ReadInteger(sec, pcMain.Name, 1) of 0: tbFavourites.Click; 1: tbExpert.Click; 2: tbFavourites.Click; end; finally if iniFile <> nil then iniFile.Free; end; end else begin // if no INI has been defined, set SQL link command as default here miSqlLinkCmdAND.Checked := true; FSqlLinkCmd := slcAnd; end; end; |
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Wenn ich da mal noch einen Einfall anmerken dürfte. Ihr seht ja, dass ich die Ini-Datei-Instanz erzeuge, aber dafür einen im klassenweiten Kontext gültigen Wert verwende (FIniFile). Wie verhält sich das bei Ini-File-Objekten, wenn mehrere Instanzen auf ein und dieselbe physische Ini-Datei zugreifen? Wird da intern nur eine gültige Instanz erzeugt (so wie bei Interfaces) oder sind das mehrere Instanzen, deren Dateioperationen über eine Art Mutex synchonisiert werden?
|
AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz
Zitat:
Ihr glaubt gar nicht, wie häufig ich schon bei Konstruktor-Aufrufen Exceptions bekommen habe; daher stehen die immer innerhalb des Try-Blocks. Und ich unterscheide nicht zwischen System-Klassen und "eigenen", da wirst ja sonst kirre! Und v.a. bringst du so was keinem Azubi bei ;) Und eine schlechte Idee ist es auch nicht, wenn man Konstruktoren "absichert"; da sind schon die dollsten Sachen bei passiert! Vorm Destruktor auf NIL zu prüfen, i.O., das sehe ich ein, das mag bei Delphi durchaus so geregelt sein, aber wer aus der C++ Ecke kommt, gewöhnt sich ganz schnell an, Objekte vorm Zerstören auf Gültigkeit zu prüfen :) Und auch hier unterscheide ich nicht: das mach ich im besten Fall immer so, dann kann ich's im Zweifelsfall auch nicht vergessen. Routine, Routine, Routine... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:35 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