![]() |
AV bei Verwendung einer INI-File
Morgen.
Ich habe folgende Klassenfunktion, mit der ich die "ID" (ein von mir für jede meiner abgeleiteten Klassen vergebener Wert) aus einer INI-Datei auslese:
Delphi-Quellcode:
Allerdings bekomme ich eine AV in der ntdll.dll.
class function TModule.GetModuleID: Cardinal;
var ini: TIniFile; begin ini:=TIniFile.Create(ModuleConfigFile); try Result:=strtoint(ini.ReadString(ClassName,'ID','0')); finally ini.free; end; end; Was könnte das bedeuten? Außerhalb dieser Klassenfunktion kann ich ohne Probleme aus der Datei lesen. |
Re: AV bei Verwendung einer INI-File
Zwei Fragen:
1.) Ist ModuleConfigFile ein Funktionsaufruf oder eine Variable? Falls es ein Funktionsaufruf ist, würde ich in der Funktion mal suchen. 2.) Warum benutzt du nicht ReadInteger statt ReadString? Gruß Hawkeye |
Re: AV bei Verwendung einer INI-File
Zitat:
|
Re: AV bei Verwendung einer INI-File
@DevilsCamp
Das war auch mein erster Gedanke. Abers selbst wenn die Variable leer ist oder ein unzulässiger Pfad drin steht, funktioniert der Zugriff auf die (nicht vorhandene) INI-Datei. Delphi liefert in diesem Fall einfach den angegebenen Defaultwert. Ich hatte eigentlich auch mit einer Exception gerechnet. :? Gruß Hawkeye |
Re: AV bei Verwendung einer INI-File
hast Recht..
@3_of_8: Hast du die AV immer oder nur bei einem bestimmten File? |
Re: AV bei Verwendung einer INI-File
Wie rufst du denn die Methode auf? Ich hab so das Gefühl, dass er bei ClassName knallt. Also prüfe, ob du eine gültige Klasse beim Aufruf benutzt.
|
Re: AV bei Verwendung einer INI-File
Zitat:
|
Re: AV bei Verwendung einer INI-File
Zitat:
Soviel kann man schon sagen, wenn man weiß, welche Parameter ReadString von TIniFile erwartet |
Re: AV bei Verwendung einer INI-File
Ich habe gerade versucht ClassName in einer class Procedure zu verwenden. Das funktioniert.
Bleibt diese ModuleConfigFile noch. Ist das vielleicht ein Property der Klasse? |
Re: AV bei Verwendung einer INI-File
Zitat:
Delphi-Quellcode:
könnte zu einer AV führe, da er ja keine gültige Klasse bekommen hat.
type
TMyClass = class of TModule; var MyClass: TMyClass; begin MyClass:=nil; ShowMessage(IntToStr(MyClass.GetModuleID)); end; Und deshalb meine Bitte. Zeig mal den Aufruf der Funktion. Eventuell übergibts du ja nil als Objekt/Klasse. p.S: Hab schon mitbekommen, dass es eine Klassenfunktion ist, aber trotzdem kann man mit dem obigen Konstrukt eine Übergabe von nil erreichen und das dürfte dann in einer AV in Classname verursachen, wenn dort keine prüfungen auf nil drin sind. |
Re: AV bei Verwendung einer INI-File
Zitat:
Delphi-Quellcode:
var
TMyClass = class(TObject) public class procedure Test; end; ... aufruf TMyClass.Test; |
Re: AV bei Verwendung einer INI-File
Selbst, wenn der Aufruf so nicht möglich ist (was ich kaum glaube, hab aber kein Delphi da um es zu überpüfen) kannst du auf jeden Fall folgendes machen:
Delphi-Quellcode:
Und es würde mich stark wundern, wenn er dann bei ClassName nicht knallt. Aber back to topic. Meine Vermutung ist, dass beim Aufruf von GetModuleID eine ungültige Klassen-/Objektreferenz vorliegt wodurch er in ClassName knallt. Allerdings kann man das erst mit Gewissheit sagen, wenn Manuel ein wenig mehr Quellcode zeigt ;)
var
Module: TModule; begin Module:=nil; ShowMessage(IntToStr(Module.GetModuleID)); end; |
Re: AV bei Verwendung einer INI-File
Wieso hängt Ihr euch eigentlich daran auf, dass die Variable ClassName heißt?
TIniFile.ReadString erwartet an erster Stelle einen STRING und nichts anderes!!!! Daher erneut meine Frage an 3_of_8: Hast du diese Probleme auch in anderen Projekten oder nur dort? |
Re: AV bei Verwendung einer INI-File
Zitat:
|
Re: AV bei Verwendung einer INI-File
Hallo,
jim_raynor hat Recht. Der Zugriff über einen Klassenzeiger führt nicht zum Fehler, der Zugriff über eine NIL-"Instanz" aber wohl. Manuel greift offenbar über eine nicht initialisierte Variable vom Typ TModule (oder eines Nachfolgers) auf die ID zu und erhält dann die beschriebene Fehlermeldung. Gruß Hawkeye |
Re: AV bei Verwendung einer INI-File
Okok. Es funktioniert beides (compilierbar), wobei das mit dem nil Pointer ne AV gibt.
Nur wissen wir immer noch nicht, wie er denn nun die Funktion aufruft. |
Re: AV bei Verwendung einer INI-File
Also:
ModuleConfigFile ist ein String, der in dem Initialization-Abschnitt einer referenzierten Unit zugewiesen wird. Die Datei existiert definitiv. Ich verwende deshalb nicht ini.ReadInteger, weil die ID als Hex-Zahl vorliegt ($0101) und ich mir nicht sicher bin, ob ReadInteger das erkennt. Ich glaube das Problem ist, dass TModuleClass(Pointer(ModuleButtons[I])).ClassName; Immer ein Leerstring ist. |
Re: AV bei Verwendung einer INI-File
aha.
Du rufst in dem Beispielcode wo doch der Fehler liegen sollte nirgends TModuleClass(Pointer(ModuleButtons[I])).ClassName; auf? Wieso ist das ein Problem, wenn dir das einen Leerstring liefert? Vielleicht dürfen wir etwas mehr von dem sehen, was den Fehler verursacht. |
Re: AV bei Verwendung einer INI-File
Du hast eine Klasse, welche eine statische Methode hat. Diese verwendet eine Variable (glaubst du zumindest), namens ClassName. Diese Variable hast du irgendwo global deklariert (in der Klasse kann nicht sein, da du in einer statischen Methode keinen Zugriff auf Klassenvariablen hast). So, da du nun aber dich in einer statischen Methode befindest, nimmt er in deiner Methode natürlich erstmal das naheliegenste, sprich: wenn vorhanden, das Element im aktuellen Gültigkeitsbereich. Dieses wäre dann _nicht_ die globale Variable ClassName sondern die in TObject definierte statische Methode namens "ClassName", welche einen String zurück gibt.
Wie man nun an der Definition von ReadString von TIniFile erkennen sollte, dass er nicht die ClassName Methode nimmt ist mir zwar schleierhaft, aber man lässt sich ja gerne belehren... So, das nur noch mal zum Hinweis. Grundlegend bringt es uns nicht weiter, da beides eine statische Methode ist und somit ein gültiges Konstrukt, auch wenn er vllt. nicht wie gewünscht die globale Variable sondern die Methode nutzt. Und zum anderen Frage ich mich, was diese ( TModuleClass(Pointer(ModuleButtons[I])).ClassName; ) abenteuerliche Konstruktion von nöten macht? |
Re: AV bei Verwendung einer INI-File
Delphi-Quellcode:
EDIT:
for I:=0 to high(ModuleButtons) do
begin showmessage(TModuleClass(Pointer(ModuleButtons[I])).ClassName); bitmap:=TBitmap.Create; bitmap.LoadFromResourceName(HINSTANCE, TModuleClass(Pointer(ModuleButtons[I].Tag)).ClassName); CreateCursorFromBMP(TModuleClass(Pointer(ModuleButtons[I])). GetModuleID(TModuleClass(Pointer(ModuleButtons[I])).ClassName),bitmap); end; Also. Ich habe KEINE Variable namens ClassName. Ich will diese statische Methode haben. Ich füge einem Panel mit einer Prozedur mehrere Buttons hinzu, jeder steht für eine Klasse abgeleitet von TModule. Im Tag desselben steckt ein Pointer auf eine class of TModule. Später lese ich das wieder aus und erzeuge eine Instanz: module:=TModuleClass(Pointer((Sender as TComponent).Tag)); |
Re: AV bei Verwendung einer INI-File
Mal castest du ModuleButtons[I].Tag, mal ModuleButtons[I] auf einen Pointer und dann auch TModuleClass - was denn nun?
Und von was für einem Typ ist das Array ModuleButtons? /EDIT: Vermutlich wird der komische TypeCast von Tag (der wohl 0 ist) auf einen Pointer ein Nil Pointer der zum Nil TModuleClass wird. Also nochmal: Warum überhaupt so komisches Konstrukt? Warum die Typensicherheit so über Board werfen? |
Re: AV bei Verwendung einer INI-File
Zitat:
Damit würdest du eine Instanz der in dem Tag enthaltene Class Of TModule Ableitung der Class of bekommen.
Delphi-Quellcode:
bzw. Wenn Module vom Typ Class of TModule ist, dann erzeugst damit eine Instanz:
module := TModuleClass(Pointer((Sender as TComponent).Tag)).Create;
Delphi-Quellcode:
Instanz := Module.Create;
|
Re: AV bei Verwendung einer INI-File
Zitat:
Wenn die Klasse naemlich von TObject abgeleitet ist (was sie immer ist), dann hast du zwar keine Variable namens ClassName, dafuer aber eine Funktion ClassName() von TObject. Allerdings gibt mir die Funktion auch bei einer class function den Klassennamen zurueck. Was willst du denn eigentlich tun/erreichen? Und warum castest du ModuleButtons[i] auf Pointer, dann auf TModuleClass, anstatt direkt ein Objekt von TModuleClass abzuspeichern? :gruebel: Irgendwie ist das krass konfus.... BTW, dieser Aufruf:
Delphi-Quellcode:
liefert immer "TModuleClass" zurueck, schliesslich castest du auf TModuleClass. Ich verstehe deine Art zu programmieren irgendwie ueberhaupt nicht :gruebel:
TModuleClass(Pointer(ModuleButtons[I].Tag)).ClassName
Greetz alcaeus |
Re: AV bei Verwendung einer INI-File
TModuleClass ist eine Class of TModule. Wenn ich dann eine Instanz davon erzeute, erzeuge ich eine Instanz eines abgeleiteten Typs von TModule. Ich will einfach beim Klick auf einen SpeedButton die damit verbundene Klasse instantiieren. Das ganze soll dynamisch und leicht erweiterbar sein.
Das funktioniert auch prima, bis darauf, dass ich in der class function GetModuleID keine INI-Datei verwenden kann. Das ist mein Problem. Wenn ich wüsste, was die ntdll.dll macht, wäre es evtl. auch einfacher. Und die Deklaration der Klasse steht nebenbei in meinem ersten Beitrag. Ich will mit ClassName den Namen der Klasse, so wie ihn ClassName() zurückgibt. |
Re: AV bei Verwendung einer INI-File
Ich zweifle an, dass man eine Metaklasse in einen Tag verbannen kann, da diese keine Instanzen haben sondern eine Typinformation sind. Kann man wirklich eine Ableitung von TModule als Klasse in einem Tag unterbringen? Die Elemente von TModuleClass sind doch keine Instanzen und somit keine Zeiger, daher die Frage ob man sie wirklich in einem Tag ablegen kann.
Ich glaube das das grundlegende Problem nicht in der GetModuleID liegt, sondern in dem Aufruf bzw. dem drumherum. |
Re: AV bei Verwendung einer INI-File
Die ntdll.dll ist der Kernel von Windows! Wenns da knallt, dann liegst nicht an der DLL selbst ...
Also versuchen wir es nochmal. 1. Wie ist ModuleButtons definiert? Wenn es als Array of TModuleClass definiert ist, dann kannst du das ganze gecaste sparen. Wenn nicht, frage ich mich ernsthaft warum nicht! 2. Wo und wie wird ModuleButtons gefüllt? 3. Ist es wirklich sehr sehr sehr verwunderlich, dass du mal:
Delphi-Quellcode:
und mal
TModuleClass(Pointer(ModuleButtons[I])).ClassName
Delphi-Quellcode:
Jetzt wo ich länger drüber nachdenke, gehe ich mal stark davon aus das du überall noch das .Tag ergänzen musst ;)
TModuleClass(Pointer(ModuleButtons[I].Tag)).ClassName
|
Re: AV bei Verwendung einer INI-File
Zitat:
Delphi-Quellcode:
Ansonsten schließe ich mich jim_raynor an, in diesen Fragen wird wohl der Knackpunkt liegen.
i := Integer(TMouse);
ShowMessage(TClass(i).ClassName); |
Re: AV bei Verwendung einer INI-File
Ich sage es nochmal: das ganze funktioniert wunderbar, bis auf das INI-File, wobei irgendwas mit ClassName() nicht hinhaut.
Das .Tag habe ich nur hier vergessen, in meinem Code stimmt das UND ES FUNKTIONIERT AUCH. ModuleButtons ist ein array of TSpeedButton. |
Re: AV bei Verwendung einer INI-File
Und alle Tags sind wirklich ungleich null?
|
Re: AV bei Verwendung einer INI-File
Hi,
Ich hatte den selber mit INIs auch mal. Du darfst für den ersten Parameter auf gar keinen Fall einen Leerstring (oder einen string der nur aus Leerzeichen besteht) zurückgeben, sonst knallts in der ntdll.dll (zumindest unter XP)! Siehe: ![]() mfG mirage228 |
Re: AV bei Verwendung einer INI-File
OK, Problem: Wieso gibt TModuleClass(Pointer(ModuleButtons[I].Tag)).ClassName einen Leerstring zurück? Und warum nur an dieser Stelle und sonst nicht? Mir schwirrt der Kopf.
Edit: É voila! Auf einmal gehts! Hab tatsächlich das .Tag vergessen und das ganze jetzt so umgangen, dass der Funktion mit dem INI-File ihr eigener Klassenname übergeben wird. Ich versteh zwar immer noch nicht, warum es manchmal mit ClassName() funktioniert und manchmal nicht, aber mit diesem Workaround gehts jetzt endlich. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 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-2025 by Thomas Breitkreuz