Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte (https://www.delphipraxis.net/173193-zugriff-auf-procedure-und-funktionen-nicht-instanziierter-klassen-objekte.html)

DSCHUCH 11. Feb 2013 19:56

Delphi-Version: XE

Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Hallo allerseits, ich bin heute nach vielen Jahren Softwareentwicklung mal wieder aus allen Wolken gefallen. Ich habe gelernt: (in Delphi?) kann auf alle Funktionen/Proceduren einer Klasse (variable) zugegriffen werden, egal ob instanziiert oder nicht.

ich habe etwas recherchiert und hier ist es auch ganz gut erklärt, wobei die erklärung am ende heißt: es ist in delphi so, da constructor und destructor.... : http://stackoverflow.com/questions/8...freeing-things

jedenfalls heißt dies, ich kann jede procedure einer klasse starten, egal ob die klasse instanziiert wurde, oder nicht. erstelle ich zB eine

Delphi-Quellcode:
procedure myform.ButtonClick;
...
myClass.doSomething(TMyInputClass.Create(Edit1.Text));


procedure TmyClasss.doSomething(InputKlasse : TMyInputClass);
begin
 If InpuKlasse.Stauts1 then
    Result:='X'
   else
    Result:=Self.Y
end;
kann ich mir nicht sicher sein, das object auf das ich zugreife überhaupt instanziiert ist, weil funktionen funktionen in bestimmten zuständen trotzdem durchlaufen werden. somit wird mir jetzt auch klar wieso man soviele "schwachsinnige" fehlermeldungen erhält, welche an nicht zuordenbaren stellen ausgelöst werden. je nachdem ob "zufällig" auf eine Variable des Objects zugegriffen wird, erhalte ich eine Fehlermeldung und ansonsten nicht.

ist dies in anderen Sprachen auch so? für mich war bisher immer ein paradigma: ich kann nur auf elemente einer instanziierten Klasse zugreifen. (ausnahmen sind zB "class procedure", "class var").

insbesondere beim schliessen einer Anwendung ist das ja interessant: je nachdem welcher finalization abschnitt zuerst durchlaufen wird, bzw. wie die erstellungsreihenfolge und somit freigabereihenfolge ist, habe ich unterschiedliche zustände und erhalte fehlermeldungen von "klassen", die vor "ewigkeiten" freigegeben wurden nur, weil zufällig eine reihe von proceduren/properties aufeinandergetroffen ist, welche nicht nachvollziehbar ist und die fehlermeldung von ganz woanders herführt, wo ein NIL-zeiger ist, der sozusagen trotzdem ausgeführt wird?!

somit ist ja auch sogleich ein stacktrace alla eurekalog/madexcept teilweise unbrauchbar. habe ich in meinem stacktrace 10 unterschiedliche klassen, ist nicht nachvollziehbar welche davon nun tatsächlich nil war, da ja "blind" alles ausgelöst wird bis eben "zufällig" auf eine lokale klassenvariable zugegriffen wird.

Mschmidt 11. Feb 2013 20:20

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Ich wage es anzuzweifeln, das man in Delphi auf Nicht statische ( class procedure) Funktionen zugreifen kann ohne das Objekt vorher zu instanziieren. Das mag vieleicht in einigen Faellen zufaellige funktionieren, ich bekomme bei sowas immer AV.
Zudem, nicht ganz von der Hand zu weisen, warum gibts dann einen Constructor/Destructor, wenn ich die Klasse nicht erzeugen muss?

... Oder steh ich grad auf'm Schlauch?

Cheers Mathias

Furtbichler 11. Feb 2013 20:30

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
So wie ich das sehe, kannst Du eine Methode, die aufgrund ihrer fehlenden Referenzen zu privaten Feldern (auch indirekt) auch statisch deklariert sein könnte, auch dann aufrufen, wenn das Objekt nicht instantiiert ist, da keinerlei undefinierte Referenzen verwendet werden.

Bjoerk 11. Feb 2013 20:57

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1202971)
Delphi-Quellcode:
myClass.doSomething(TMyInputClass.Create(Edit1.Text));

Logo, du hast ja innerhalb von myClass.doSomething die Instanz TMyInputClass.Create.

Furtbichler 11. Feb 2013 20:59

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Ja ja, aber
Delphi-Quellcode:
myClass
ist doch nicht instantiiert, und dessen Methode wird aufgerufen....

Bjoerk 11. Feb 2013 21:06

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Ja sicher, in dem Moment, wo er TMyInputClass aber erzeugt, ist die doch verfügbar?

Lemmy 11. Feb 2013 21:18

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
genau und damit greift er, wie Furtbichler es schon geschrieben hat, auf Elemente zu, die initialisiert sind. Sobald er auf ein Feld der eigenen KLasse zugreift geht es schief.

Bjoerk 11. Feb 2013 21:19

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Beispiel:

Delphi-Quellcode:
type
  TMyStringList = class(TStringList)
    procedure DoSomeThing(List: TMyStringList);
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;


procedure TMyStringList.DoSomeThing(List: TMyStringList);
begin
  List.Add('Test');
  ShowMessage(IntToStr(List.Count));
  // ShowMessage(IntToStr(Self.Count)); *** AV
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  List: TMyStringList;
begin
  List.DoSomeThing(TMyStringList.Create);
  List.Free;
end;

end.

Furtbichler 11. Feb 2013 21:32

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
nein, der Parameter 'InputKlasse' ist instantiiert, aber nicht die Instanz 'MyClass', dessen Methode aufgerufen wird.

DSCHUCH 11. Feb 2013 21:42

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
sehr gut, ich bin nicht der einzige der da schaut wie ein pferd ins uhrwerk. ;)

hier mal ein einfaches bsp.

Delphi-Quellcode:
  Tc = class(TComponent)
    private
     F : TComponent;
     class var I : Integer;
     function GetPrivateF : String;
    public
     procedure t;
    published
     property getF : String read GetPrivateF;
  end;

function Tc.GetPrivateF: String;
begin
 ShowMessage('Here i am');
 Application.ProcessMessages; //wir aufgerufen von einem nicht existierenden Objekt!!!
 Application.DoSomething(Self); //ruft eine weitere Methode aus nicht exisitierendem Objekt auf, mit einem NIL zeiger auf Self.
 Exit('Ok')
end;

procedure Tc.t;
begin
 ShowMessage('test');
 if Assigned(Self) then
    ShowMessage('Self is Assigned')
   else
    ShowMessage('Self is not Assigned');//analog Free (wo ich geacht hätte es wäre eine art class procedure und daher mit nil aufrufbar)
end;


procedure TForm6.Button1Click(Sender: TObject);
var C : TC;
begin
 C:=nil;
 //ShowMessage(C.Name);
 ShowMessage(C.getF);
end;

procedure TForm6.Button2Click(Sender: TObject);
var C : TC;
begin
 C:=nil;
 //ShowMessage(C.Name);
 C.t;
end;

Lemmy 11. Feb 2013 22:03

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1202984)
hier mal ein einfaches bsp.

Was zum Geier ist daran einfach? Zudem greifst Du wieder nicht auf ein Feld/Variable der nicht instanziierten Klasse zu.


Delphi-Quellcode:


  TTest = class(TObject)
  private
    FTestProperty: Integer;
  public
    procedure DoSomething;
    function DoAnything: Integer;
    property TestProperty: Integer read FTestProperty write FTestProperty;
  end;


function TTest.DoAnything: Integer;
begin
  result := FTestProperty + 1;
end;

procedure TTest.DoSomething;
begin
  ShowMessage('Hallo Welt');
end;


procedure TForm1.Button1Click(Sender: TObject);
var Test: TTest;
begin
  Test.DoSomething;
  Test.TestProperty := 10;
  ShowMessage(IntToStr(Test.DoAnything));
end;


Und jetzt das Entscheidende: Schalte die Optimierung von Delphi aus! Sonst bekommst Du erst am Ende einen Zugriffsfehler!

jfheins 11. Feb 2013 22:07

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Klar geht das. Eine Methode ist eben auch nur Code.
Sicher, es ist böse und risikoreich - aber es lassen sich eben auch schlechte Programme compilieren.

Mit ein bisschen Glück bekommst du aber eine Warning in der sowas steht wie "Zugriff auf nicht initialisierte Variable" oder so.

Falls du natürlich auf Daten der Klasse zugreifst ist das noch viel böser und fliegt dir im besten Falle sofort mit einer AV um die Ohren :P

DSCHUCH 11. Feb 2013 22:21

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von Lemmy (Beitrag 1202986)
Was zum Geier ist daran einfach?

worum es geht ist denke ich klar. ;)

Zitat:

Zitat von Lemmy (Beitrag 1202986)
Zudem greifst Du wieder nicht auf ein Feld/Variable der nicht instanziierten Klasse zu.

das ist ja genau der Punkt. Es ist absoluter zufall und partout nicht nachvollziehbar, woher ein fehler kommt. wir haben zB derzeit einen stacktrace eines fehlers, natürlich 1-2 mal die Woche (oder auch nicht), wo zig klassen und property-reader vorkommen. somit is nicht mehr nachvollziehbar, wo der fehler eigentlich entstanden ist. ich kann nur dann, wenn ich jetzt genau jede klasse untersuche und nachschaue wo auf reader und wo das erste mal auf eine interne variable zugegriffen wird bewerten, wo es theoretisch sein könnte. habe ich den quellcode nicht, ist es gar nicht nachvollziehbar.

interessant wird es umso mehr, wenn man klassen weiterentwickelt. so habe ich zB in der vergangenheit manchmal klassenvariablen zu properties verändert, um eine nachträgliche vererbung zu implementieren.

Delphi-Quellcode:
zB: TMyClassNew und TMyClassOld implementieren beide ein und dasselbe Interface.

class Base=class
 FistVersionVar : TMyClass;
end; //alte version

class BaseV1=class(Base)
 property FirstVersionVar : TMyClassOld read FGetMyClass;
end;

class BaseV2=class(Base)
 property FirstVersionVar : TMyClassNew read FGetMyClass;
end;
Zitat:

Zitat von Lemmy (Beitrag 1202986)
Und jetzt das Entscheidende: Schalte die Optimierung von Delphi aus! Sonst bekommst Du erst am Ende einen Zugriffsfehler!

[/QUOTE]

was ändert das muß ich jetzt fragen? erhalte ich dann einen anderen stack trace/ die AV an einer anderen stelle?

Lemmy 11. Feb 2013 22:55

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1202992)
Zitat:

Zitat von Lemmy (Beitrag 1202986)
Zudem greifst Du wieder nicht auf ein Feld/Variable der nicht instanziierten Klasse zu.

das ist ja genau der Punkt. Es ist absoluter zufall und partout nicht nachvollziehbar, woher ein fehler kommt.

ich habe irgend wie das Gefühl wir reden aneinander vorbei...

Zitat:

Zitat von DSCHUCH (Beitrag 1202992)
Zitat:

Zitat von Lemmy (Beitrag 1202986)
Und jetzt das Entscheidende: Schalte die Optimierung von Delphi aus! Sonst bekommst Du erst am Ende einen Zugriffsfehler!

was ändert das muß ich jetzt fragen? erhalte ich dann einen anderen stack trace/ die AV an einer anderen stelle?

ja. Der kommt an einer anderen Stelle - eben weil der Optimierer bei schlechtem Code Blödsinn macht.

Medium 12. Feb 2013 00:06

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Der Hintergrund ist folgender: Der Code jeder Klasse besteht immer. Eine Klasse ist im Speicher nichts weiter, als ein Stück Feld-Definitionen für den Fall der Instanziierung, und ein Stück, in dem alle Methoden inkl. deren Code steht. Eine Instanz bekommt NICHT je ihre ganz eigene Kopie des Codes, sondern verweist immer nur auf die Speicherstelle, an der die Klassendefinition sie stehen hat. (Bzw. die jeweilige Elternklasse, oder es wird die VMT bemüht wenn es um virtuelle Methoden geht.) Der Code ist ab Programmstart einfach IMMER da. Die Felder auf die ggf. zugegriffen wird, sind es jedoch nicht.
Weist man also einer Variablen eine Instanz zu und zerstört diese ohne "nillen", so hat man wunderbar nachher Zugriff auf die Methoden, selbst wenn der Speicher der Instanz längst überschrieben wurde. Der Compiler weiss ja von welchem Typ die Referenz ist, und verweist munter auf die jeweiligen Stellen im Code-Segment, völlig egal ob da eine Instanz ist oder nicht.

Technisch gesehen ist dies sogar nichtmals ein Fehler, da die Methoden ja da sind! Da man (der Compiler) nicht immer 100%ig wissen kann, ob in diesen auf Felder zugegriffen wird, die möglicherweise nicht existieren, geht das auch durch den Compiler. Im günstigsten Fall mit Warnung, aber an und für sich ist da aus technischer Sicht nichts falsch dran. Man muss halt aufpassen. Und ja, das ist in anderen Sprachen auch so, wenn gleich einige solche Dinge besser erkennen können, und ggf. gleich ganz die Kompilierung untersagen. Zwingend ist das nicht.

Statische Methoden sind unter der Haube fast mit "normalen" identisch. Hier sagt man dem Compiler nur explizit: Wenn das hier aufgerufen wird, stelle mir bitte sicher, dass ich nur auf Dinge zugreife, die bereits mit der nackten Klassendeklaration in Existenz gerufen wurden! (Also andere statische Methoden für die das sicher gestellt wurde, und Klassenvariablen.) (Zudem lassen diese sich dann über den Namespace der Klasse aufrufen, nicht (nur) über eine Instanz-Referenz.) Ansonsten stehen die genau so im Codesegment wie alles andere auch. (Und, Spezialfall Delphi, "self" wird anders behandelt.)

TL;DR: Der Code ist immer da, und steht genau ein Mal pro Klasse im Speicher (egal wie viele Instanzen). Er wird immer nur von dieser einen Stelle aus aufgerufen, der Compiler ist dafür verantwortlich. Eine Instanz braucht es für den blanken Aufruf nicht, der Code ist schließlich vorhanden. Manche Sprachen prüfen sowas strikter ab, es ist aber nur ein formaler/semantischer Fehler - kein technischer/syntaktischer. Manche stellen sowas in die Verantwortung des Programmierers (und warnen ggf.), andere versuchen das ganz zu unterbinden (wodurch manche Hacks allerdings auch unmöglich werden). Delphi gehört zu ersterem, und das ist völlig in Ordnung.

Furtbichler 12. Feb 2013 06:50

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Man muss eben wissen, das Delphi nicht das Modernste an Programmiersprache ist, was es auf der Welt gibt. Da kommt sowas schon mal vor.

Abhilfe:
1. Ordentlich programmieren (Erzeugerprinzip verwenden, d.h. wer instantiiert, gibt auch frei)
2. Unit-Tests
3. FastMem einbauen

Nicht instantiierte Objekte hatte ich sehr selten (z.B. wenn ein Objekt per Message weitergeleitet wird und nicht klar ist, wie lange es lebt). Aber das ist ja auch ein Verstoß gegen (1)


Ich glaube, FastMem findet die Fehler, bei denen ein nicht instantiiertes Objekt verwendet wird.

DSCHUCH 12. Feb 2013 19:48

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
hm... technisch ist klar, was wie wo und warum.

andererseits ist mir jetzt auch klar, wieso ich noch nie eine (komplexere) delphi anwendung ohne AV gesehen habe, selbst die IDE immermal knallt mit den sinnlosesten fehlermeldungen von den blödsinnigsten units/zeilen etc. :P

1) was mich jetzt noch mal interessiert ist, wie dann eigentlich proceduren implementiert sind, welche auf (windows-) messages reagieren (zB Painter). da der code ja immer vorhanden ist, unabhängig der klasseninstanz, muß ja irgendwo geregelt werden, welche instanz nun die message erhält, und welche nicht. ist es theoretisch vorstellbar, das eine nil-klasse eine message (zB wm_paint) erhält?

2) was ändern FastMem bzw. die Code Optimierung an dem ganzen?

Furtbichler 12. Feb 2013 20:49

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1203163)
hm... technisch ist klar, was wie wo und warum.

Angesichts deiner weiteren Ausführungen zweifle ich, ob Du es wirklich begriffen hast.
Zitat:

andererseits ist mir jetzt auch klar, wieso ich noch nie eine (komplexere) delphi anwendung ohne AV gesehen habe, selbst die IDE immermal knallt mit den sinnlosesten fehlermeldungen von den blödsinnigsten units/zeilen etc. :P
Das schmerzt. Ich sehe das bei *jedem* Programm, egal in welcher Sprache.

Zitat:

2) was ändern FastMem bzw. die Code Optimierung an dem ganzen?
Alter Schwede. FastMem *zeigt* dir den Fehler (steht auch im Beitrag) und der Optimierer (steht auch da) sorgt eben beim 'wegkürzen' von Code dafür, das der Fehler u.U. in einer anderen Stelle angezeigt wird. Seufz.

Dir fehlen entscheidende Grundlagen, um hier mitreden bzw. kritisieren zu können. Schreib einfach saubere Programme, das ist schon schwer genug.

JamesTKirk 13. Feb 2013 08:54

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1203163)
1) was mich jetzt noch mal interessiert ist, wie dann eigentlich proceduren implementiert sind, welche auf (windows-) messages reagieren (zB Painter). da der code ja immer vorhanden ist, unabhängig der klasseninstanz, muß ja irgendwo geregelt werden, welche instanz nun die message erhält, und welche nicht. ist es theoretisch vorstellbar, das eine nil-klasse eine message (zB wm_paint) erhält?

Innerhalb des Constructors eines Formulars wird die WndProc gesetzt, welche von Windows die Nachrichten enthält. Diese Nachrichten werden dann (einfach formuliert) per
Delphi-Quellcode:
Form.Dispatch
an das jeweilige Form geschickt.
Delphi-Quellcode:
Dispatch
ist in
Delphi-Quellcode:
TObject
deklariert und sucht sich an Hand der Nachrichtentabelle des Objekts die passend
Delphi-Quellcode:
message
Methode raus oder ruft, falls es keine gibt, die virtuelle Methode
Delphi-Quellcode:
DefaultHandler
auf.

Rein theoretisch sollte das auch mit einer ungültigen Instanz funktionieren, aber wie jeder Hack ist diese Angabe ohne Gewähr.

Gruß,
Sven

DSCHUCH 13. Feb 2013 22:55

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Liste der Anhänge anzeigen (Anzahl: 1)
erstmal danke für die antworten.

im Anhang habe ich mal ein bsp für einen StackTrace eines Fehlers angehangen, welchen ich derzeit provozieren kann, indem ich im start einer anwendung sofort ein Terminate einbringe (mittels timer, ich bin zufällig auf den effekt gestossen). Offensichtlich wird hier die hälfte der anwendung freigegeben, dann eine Message bearbeitet (wm_killfocus). Die Komponenten dürften bekannt sein, sodass vermutungen wie Spagetticode ausgeschlossen werden können. (DevExpress)

Wie man sieht: keine einzige Zeile eigener Quellcode. (oder eben schon entladen)

Ich habe jetzt mal grob die DevExpress quellen überflogen (eigentlich keine Zeit diese tage für solche Spielereien) und darin enthalten sind mehrere globale VariablenInstanzen, etc pp. da der Stacktrace durchklappert bis zum ersten Zugriff auf ein Klassenfeld, kann ich jetzt rätselraten, ob die vorherigen objekte nun instanziiert sind, oder der code zufällig so aufgebaut ist, das bis zuletzt nicht auf felder zugegriffen wird.

Zitat:

FastMem *zeigt* dir den Fehler (steht auch im Beitrag) und der Optimierer (steht auch da) sorgt eben beim 'wegkürzen' von Code dafür, das der Fehler u.U. in einer anderen Stelle angezeigt wird.
hier reden wir aneinander vorbei, was es theortisch macht ist mir auch wieder klar, was es praktisch wirklich ändert ist die frage. ich weiß zB nicht, ob man mit diesen/irgendwelchen Tools die Speicher komplett ausnullen kann, wenn ein objekt freigegeben wird, sodas es halt nicht mehr zufällige zugriffe auf zufällig vorhandenen code gibt.

Zitat:

Dir fehlen entscheidende Grundlagen, um hier mitreden bzw. kritisieren zu können.
Richtig. Ich bin Anwendungsentwickler und mein Fokus liegt darauf, mit Unternehmen Prozesse zu entwerfen und diese in eine Softwarestruktur zu bringen. Es interessiert mich grundsätzlich auch nicht, wie der Compiler etwas macht und wie nicht, würde mich das interessieren, wäre ich "richtiger Softwareentwickler" geworden und ich habe auch keine Zeit mehr für diese Dinge. ;)
Da man bei solchen Fehlern wie zB den oben von Entwicklern idR hört "da war irgendwas nicht instanziiiert" und "das ist nicht nachvollziehbar" (ist ja auch so, wir haben das bei paar Hunder Anwendern bei manchen paar mal die Woche (alle 2-3 Tage), bei teilweise 24*7 Betriebsdauer der Software {Verwaltungssoftware Unternehmenssteuerung}), beschäftige ich mich derzeit halt doch mal wieder mit solchen dingen, da ich eher sehe wie Anwender eine Software bedienen und somit teilweise besser Rückschlüsse auf technische Abläufe/Zusammenhänge ziehen kann. Es geht ja zB schon damit los, das es für viele Bediener nur Doppelclick gibt, einfach klick gibt es nicht.

(daher haben wir mit vielen manwochen aufwand alle Application.processmessages ersetzt, da liegen ordner auf der tastatur während es rechnet, es werden zufällige tasten gedrückt, zum schluß kilbert es, da die anwendung irgendwelche eingaben verarbeitet hat)

Letzendlich ist die Frage, wie man in solchen Fällen von zufälligen Fehlern, welche meist im Stacktrace auf Codezeilen verweisen die nicht mal in den eigenen Bibliotheken liegen ein Debugging/Eingrenzung vornimmt.

Zitat:

Dispatch ist in TObject deklariert und sucht sich an Hand der Nachrichtentabelle des Objekts die passend message Methode raus oder ruft, falls es keine gibt, die virtuelle Methode
muß ich nachlesen, wie sich die WinControls da registrieren/deregistrieren und ob es möglich ist, das hier noch eine komponente/methodenzeiger in der Nachrichtentabelle steht, welche nicht mehr existiert.

Furtbichler 14. Feb 2013 07:27

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von DSCHUCH (Beitrag 1203400)
im Anhang habe ich mal ...Ich bin Anwendungsentwickler ... Es interessiert mich grundsätzlich auch nicht, wie der Compiler etwas macht ...würde mich das interessieren, wäre ich "richtiger Softwareentwickler" geworden und ich habe auch keine Zeit mehr für diese Dinge. ;)

Merkste wat? Lass die Finger vom Maschinenraum, Du störst die Leute bei der Arbeit. :lol:

Ich bin Abteilungsleiter (IT), war vorher Projektmanager, davor 25 Jahre Softwareentwickler und kenne mich ganz gut im Maschinenraum aus (eine Voraussetzung auch für Anwendungsentwickler, die mitreden wollen, finde ich). Ich habe erstens Zeit für *diese* Dinge, aber was noch wichtiger ist: Ich habe Zeit für die Dinge, die zu meinem Aufgabenbereich gehören, insofern beißt es sich nicht, sich dafür zu interessieren.

Es ist trotzdem Ok, das Du dich in deinem Aufgabengebiet abgrenzt (der eine so, der andere so), aber um bei der Diskussion der Probleme der Softwareentwickler mitreden zu können, brauchst Du ein wenig mehr, als ziellos im Code herumzustochern. Das ist so, als ob der Prozessmanager einer Klinik planlos in der Bauchhöhle eines Patienten rumpopelt, weil er bei Operationsfehlern mitreden will, obwohl ihn Anatomie eigentlich gar nicht interessiert.

Deinen Entwicklern könnte(!) das Augenmaß für robusten Code fehlen. Wenn 'da irgendwas nicht instantiiert' ist, dann ist das ein Designfehler (wenn es kein Bug in einer Library ist). Und: DevExpress ist bekannt dafür, das es zickig reagiert, wenn man die Klassen nicht so verwendet, wie man sollte. Ganz spaßig ist das Verwenden von Events dort, wo sie nicht verwendet werden sollen (Stichwort: Ordner auf Tastatur)

Es ist auch eine ganz schlechte Angewohnheit, die Komponenten 'erst mal auf die eigenen Bedürfnisse umzuprogrammieren' (kein Vorwurf an deine Leute), denn das geht meistens in die Hose. Wer versteht schon zu 100%, wie das bei DevExpress funktionert?

Mein Tipp: Wendet euch an den DevExpress-Support, um die kreative Verwendung der Events auf Korrekteit abzuklopfen. Insbesondere wenn sich der Fokus in einer GridView ändert, passiert intern bei DevExpress viel: Da werden Objekte neu instantiiert usw. Da muss man sich dann nicht wundern, wenn einem bei falscher Verwendung der Events die Anwendung um die Ohren fliegt. Das ist aber kein Bug von DevExpress, sondern einfach ein Seiteneffekt wegen Nichteinhaltung der DevExpress-Philosophie.

So wie ihr da rangeht (Auswechseln von 'Application.Processmessages' ist nicht zielführend) sieht es auch nicht so aus als ob ihr wisst, was ihr tut. Ich war aber selbst mal in dem Stadium (DevExpress, Anwender, Ordner, Peng) und weiss, wie planlos man da ist. Echt zum Haareraufen. Ich habe angefangen, die Problem einzugrenzen, indem ich Event für Event abgeschaltet habe. Und dann habe ich mich an den Support gewandt und gefragt, wie man dieses Feature denn richtig einsetzt.

DSCHUCH 14. Feb 2013 17:07

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte
 
Zitat:

Zitat von Furtbichler (Beitrag 1203420)
Merkste wat? Lass die Finger vom Maschinenraum, Du störst die Leute bei der Arbeit. :lol:

würde man das als projektleiter machen, wäre der maschinenraum ganz schnell unter wasser, da der kunde nie ein produkt erhält oder die kosten ein loch in den maschinenraum reissen und der ganze laden sinkt. :cyclops:

Zitat:

Zitat von Furtbichler (Beitrag 1203420)
Es ist trotzdem Ok, das Du dich in deinem Aufgabengebiet abgrenzt (der eine so, der andere so), aber um bei der Diskussion der Probleme der Softwareentwickler mitreden zu können, brauchst Du ein wenig mehr, als ziellos im Code herumzustochern.

geht ja wohl kaum anders, der tag hat nur 28 Stunden ^^.

letztendlich brauche ich als anwendungsentwickler vernünftige grundlagen, um ein ordentliches design zu entwerfen. wie dies dann technisch umgesetzt wird, ist dann natürlich etwas anders. prinzipiell hat aber jeder, wer informatik beim studium hatte, dinge wie A&D, Betriebssysteme, Threading-Modelle etc gelernt. das dann anwendungen _manchmal_ knallen, sind spezifika und seiteneffekte, die man nicht theoretisch lernt sondern im detail lösen muß. wie tief man in die programmierung einsteigt ist am ende ja immer sehr aufgabenabhängig. ich habe viele jahre vollzeit rad entwicklung betrieben, das nutzt einem aber bei tiefgreifenden problemen nichts, man kennt aber eben die seiteneffekte.

Zitat:

Zitat von Furtbichler (Beitrag 1203420)
Deinen Entwicklern könnte(!) das Augenmaß für robusten Code fehlen. Wenn 'da irgendwas nicht instantiiert' ist, dann ist das ein Designfehler (wenn es kein Bug in einer Library ist). Und: DevExpress ist bekannt dafür, das es zickig reagiert, wenn man die Klassen nicht so verwendet, wie man sollte. Ganz spaßig ist das Verwenden von Events dort, wo sie nicht verwendet werden sollen (Stichwort: Ordner auf Tastatur)

das würde ich bestreiten. man muß sehen, das bei einer Anwendung wie unserer, mit ca. 400 Formularen, dynamischen bpl und dll, [alles wird bei bedarf dynmaisch geladen] Datenbank im Hintergrund von 10GB mit 300 tabellen, und seit ca. 2 jahren datasnap, über das permanent massen an daten zwischen client und server ausgetauscht werden. hinzukommen netzwerke im unternehmen, seiteneffekte wie netzwerkabrisse, virenscanner etc.pp

vor kurzem hatten wir zB das problem, das die ExitProc einer dll nicht mehr sauber arbeitet, was unter delphi7 noch sauber lief, ob es nun daran lag, auch wieder kA, wir haben dann eben die dinge in die finalization einer unit umgelegt, mit dem bewußtsein das solche änderungen halt seiteneffekte hervorrufen können. du mußt sehen das unseer code zum teil >10 jahre alt ist, dann hat man nicht mehr überall bilderbuchdesign, insb. auch daher das man viele externbibilotheken mit wieder eigenen "besonderheiten" berücksichtigen muß.

Zitat:

Zitat von Furtbichler (Beitrag 1203420)
Es ist auch eine ganz schlechte Angewohnheit, die Komponenten 'erst mal auf die eigenen Bedürfnisse umzuprogrammieren' (kein Vorwurf an deine Leute), denn das geht meistens in die Hose. Wer versteht schon zu 100%, wie das bei DevExpress funktionert?

Hier ist aber die notwendigkeit nunmal entscheidend. in unserer anwendung sind nahezu alle komponenten abgeleitet, um bessere kontrolle zu haben, oder auch schon nur wegen kompatibilität und austauschbarkeit. unsere anwendung war früher devexpress version 3, dann portiert, portiert, portiert.... ohne eine ordentliche ableitung der verwendeten standardkomponenten kann man das vergessen bei hunderten von Formularen.
Aber das ist auch nochmal ein ansatz, welchen wir intern disktuieren müssen, evtl kann man hier die fehlerkontrolle verbessern.

Zitat:

Zitat von Furtbichler (Beitrag 1203420)
Mein Tipp: Wendet euch an den DevExpress-Support, um die kreative Verwendung der Events auf Korrekteit abzuklopfen.

der devexpress support ist spitze, wir haben schon sehr viel mit denen gearbeitet, bugfixes erhält man idR innerhalb weniger tage.
nutzt aber nichts wenn man keine rekonstruierbaren fälle hat, insb. da - (anfang der diskussion) der fehler ja nichtmal von dort kommen muß, selbst wenn der stacktrace darauf zeit. ^^

Zitat:

Zitat von Furtbichler (Beitrag 1203420)
So wie ihr da rangeht (Auswechseln von 'Application.Processmessages' ist nicht zielführend) sieht es auch nicht so aus als ob ihr wisst, was ihr tut.

hat bei uns diese probleme beseitigt. wir haben alles gekapselt und haben jetzt die möglichkeit alle "zeichenroutinen" der kompletten anwendung zentral und über parameter zu steuern.

Application.ProcessMessages ist meines erachtens nach eines der dümmlichsten dinge in delphi, insb. da überall steht "verwenden, bei längeren operationen, damit die anwendung nicht hängt, bzw. zeichnen zu lassen."

so zB habe ich das erst vor 3 tagen hier gelesen, hatte aber gerade keine zeit: http://www.delphipraxis.net/173225-f...leife-auf.html

prinzipiell müßte ja wenigstens die form disabled und enabled werden, damit der nutzer zB die anwendung nicht während der bearbeitung der schleife schliesst. noch interessanter wird es, wenn er die funktion in einem eventhandler einbaut (buttonclick)

letztendlich sagst du aber auch, das du die fehler nur durch haare raufen :thumb: sowie try except herausgefunden hast. wir werden sicher bei der nächsten entwicklersitzung erstmal deinen vorschlag disktuieren und die ganzen devexpress events (bzw überschriebene proceduren, ableitungen etc) auf unregelmäßigkeiten überprüfen. ich könnte mir jetzt vorstellen das dort in irgendeinem fall mal ein abort ausgelöst wird, was mir jetzt einiges erklären könnte und auch deinen ansätzen gleich käme. (zB in einer überschriebene methode "focuschange" eines objektes, um zu verhindern das weitere abarbeitungen stattfinden)


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