Zuverlässigkeit der Functionen



  • hi,

    ich glaube jeder, der schon einmal an einem etwas größeren programm mitgewirkt hat kennt diese effekte, das nach änderungen, funktionen, die vorher bestens liefen auf einmal sonderbare dinge machen. man denkt zwar zuerst, das gibt es nicht, function x hat doch nix mit function t zu tun, aber in vielen fällen beinflussen sich die beiden dann eben doch irgendwie. meistens sind es dann kleinigkeiten und das ding läuft wieder, das problem ist nur, das sehr lange dauern kann bis man diese kleinigkeiten findet. aber aufgrund dieser umstände habe ich es mir wenigstens angewöhnt regelmässig länger mit dem debugger zu arbeiten...

    mfg
    murph



  • @phänomen bekannt, für die Infos dank ich dir. Es ist beruhigend zu wissen, daß das Prob allemal auch Profis wohlbekannt ist und völlig normal. Die vernetzungen betreffen ja nicht nur den erstellten Code sondern reichen bis in die Tiefen der Lib hinein. Der Debugger führt mich immer wieder in die includes.

    Na ja, mein Beispiel war natürlich nur gedacht, um die Situation besser beschreiben zu können. Kann natürlich keine Höffnung auf Hilfe haben - sonst hätte ich einen gezielten Thread aufgemacht. Aber wie man Fehler erkennt, die sich aus feinen Vernetzungen ergeben, ich glaub nicht, daß ich das schon ansatzweise gelernt hab. Also unbeirrbar bleiben und weiter üben. Deine Infos können den Mut dazu vermitteln, hab nochmals vielen Dank. 🙂



  • naja... ich würde zum beispiel den code aus HellerClick in eine separate funktion auslagern. schliesslich hat das nix mehr mit dem klick auf nen button zu tun, sondern ist, ne allgemein bildverarbeitende routine, die du mit übergabe eine bitmap-paramenters ausführen solltest. steigert enorm die übersichtlichkeit und so sind fehler auch leichter zu finden.

    und so en schnulli wie irgendwelche tmp-aufrufe von funktionen, damit eine andere funktion geht, solltest du ganz schnell lassen und lieber noch mal deinen code durchguggen solange der noch so mengenmässig klein ist.

    was passiert denn wenn du das invertieren weglässt?
    passiert gar nichts?
    steigt die funktion mit ner fehlermeldung aus, wenn ja welcher?
    wo ist der try und catch block um den funktionscode um fehler abzufangen?



  • Voreg, den Schnulli würd ich gern lassen. Das ist kein Programmieren sondern Krampf. Die Function läuft ohne den Kram im Debugger fehlerfrei durch. Hab mir ein 2x2-Testbild gebaut, um schnell sehen zu können, was in und nach Schleifen passiert.

    Außerhalb vom Debugger bringt die Function ohne den Zusatzkram auch keine Fehlermeldung. Aber ich kann sie 100 mal aufrufen, ohne ein Ergebnis zu erhalten. Mit dem Krampf erhalte ich ein Ergebnis, das Bild wird bei jedem Tastendruck heller.

    Jetzt hab ich Verständnisprobleme, @Sunday. Bisher verstand ich es so, daß ein OnClick ein Ereignis auslösen kann. Wenn das falsch ist, wie löse ich die Function denn aus? Diese Funktion hat die einzige Aufgabe, das Bild heller zu machen.

    Wenn ich deine Empfehlung umsetz, hab ich 2 Functionen statt einer. Nach meinem jetzigen Verständnis würde das die Übersichtlichkeit sogar reduzieren. Vielleicht doch nicht, wenn ich es mal kapiert hab?

    Aber hier hab ich noch keine Anleitung gefunden. Mir ist nicht klar, was ich jetzt zu tun hätte. Und... müßte ich dann nicht alle OnClick-Routinen an spezifische Routinen weitergeben? Kein einziges Ereignis in der App hat ja was mit dem OnClick selbst zu tun.



  • ja das ist schon richtig. aber was ist, wenn du mal irgendwann wieder die routine benoetigst um ein bild heller zu machen? besser isses da die eigentliche funktion auszulagern und im onclick auf diese funktion zu verweisen. du erstellst dir also eine bibliothek mit den ganzen programmfunktionen, bild heller, dunkler, grau machen, usw.. diese bibliothek kannst du einfach spaeter in anderen projekten wieder verwenden. wenn du die einmal fertig hast un weisst, dass alles funktioniert, brauchste die auch nie mehr an zu packen und kannst die funktionen einfach aufrufen und weisst, dass du das richtige ergebnis gekommst. fuer den anfang musste ja nicht mal unbedingt ne dll erstellen, sondern da reicht es aus die funktionen in einer separaten unit auszulagern.

    kleines beispiel wie ich das ungefaehr meine... ungetestet...

    void ImageBMP_RGBToGray(TImage *Image)
    {
      Graphics::TBitmap *bmp_gray = new Graphics::TBitmap();
    
      // bild zu weisen  
      bmp_gray->Assign(Image->Picture->Bitmap);
    
      for (int j = 0; j < bmp_gray->Height; j++)
      {
        RGBTRIPLE *SL = (RGBTRIPLE *) bmp_gray->ScanLine[j];
    
        for (int i = 0; i < bmp_gray->Width; i++)
        {
          BYTE gray;
    
          gray = (SL[i].rgbtRed * 0.299) + (SL[i].rgbtGreen * 0.587) + (SL[i].rgbtBlue * 0.114);
    
          SL[i].rgbtRed   = gray;
          SL[i].rgbtGreen = gray;
          SL[i].rgbtBlue  = gray;
        }
      }
    
      // dem image wieder zu weisen
      Image->Picture->Bitmap->Width  = bmp_gray->Width;
      Image->Picture->Bitmap->Height = bmp_gray->Height;
      Image->Picture->Bitmap         = bmp_gray;
    
      delete bmp_gray;
    }
    
    void __fastcall TForm1::HellerClick(TObject *Sender)
    {
      RGBToGray(Image1);
    }
    


  • Die Argumente gefallen mir, @Sunday. Wiederverwendbar ist ein handfestes Argument. Es harmoniert auch mit meinem Ordnungssystem. Ich faß zusammenhängende functionen in Functionsgruppen zusamen. Die erste Gruppenfunction bekommt einen
    // Heller
    Kommentar in die Zeile darüber. Ist 'ne prima Orientierungshilfe.

    Hab die Funktion als

    void __fastcall TPixi::BildHeller(TImage *Image)

    declariert. Erweiter ich bei der reinen void function die Parameterliste um die benötigten private declarierten Variablen, findet sie der Linker als unresolved external. public kommt ja nicht infrage. Was anderes würde mir aber nicht einfallen. Also der Punkt bleibt erst mal unklar.

    Geholfen hat es übrigens auch nicht. Die function läuft durch, die Variablenwerte sind bekannt, aber das Bild wird nicht verändert. Da is guter Rat erst mal teuer. Aber du hast Recht. Es macht keinen Sinn, weiterzugehen, solang das noch nicht geklärt ist. Das wird ja sonst immer schlimmer und unübersichtlicher... Und ich hab erst mal keinen Ansatz zum Suchen. 😞



  • Hi Omega-X

    Also bei mir klappt das hier: (ist leicht mit Variablen angepasst!)

    Byte *ptr;
      Byte *aptr;
      Graphics::TBitmap *hellpict = new Graphics::TBitmap();
      hellpict->Width = Image1->Picture->Graphic->Width;
      hellpict->Height = Image1->Picture->Graphic->Height;
      hellpict->Assign(Image1->Picture);
      hellpict->PixelFormat = pf24bit;
      int i,j;
      for (i=0;i < hellpict->Height;i++)
      {
        ptr = (BYTE *)hellpict->ScanLine[i];                   // Zeile des Originals
        aptr = (BYTE *)Image1->Picture->Bitmap->ScanLine[i];// neu zu zeichnende Zeile
        for (j=0;j < hellpict->Width;j++)
        {
          for (int z = 0; z < 3; z++)
            ptr[j*3+z] = (aptr[j*3+z]+12>255?255:aptr[j*3+z]+12);
        }
      }
        Image1->Picture->Bitmap->Assign(hellpict);
        delete hellpict;
    

    Ist in OnClick des Button

    PS: Ich nehm' immer pf24bit!!!



  • Hi DerAktenburger!

    Gut, hab das PixelFoemat von hellpict fest auf pf24bit eingestellt.
    Die (int) pf = 3 sind beim Debuggerdurchlauf bekannt. Hab aber jetzt die pf in der Schleife gegen '3' ausgetauscht. Jetzt muß kein Variablenwert mehr berücksichtigt werden. Trotzdem wird das Bild nicht heller. Nur einmal auf "Graustufen" getippt, danach funktioniert "Heller" einwandfrei.

    Also das ist echt komisch. Du hast eine riesengroße App geschrieben (andere ja auch), und alle Functionen klappen. Also liegt es nicht an der Größe.

    Der Debugger scheint mir da nicht weiterhelfen zu können. Er kann nicht mehr als sagen, daß alles benötigte vorhanden ist und daß die Function komplett durchläuft.

    Was kann die Ausführung verhindern, wenn doch alles da ist? - Mal 15.000 Volt draufgeben zum Anregen? Aber selbst Verbrecher werden nur mit 5000 V bestraft. 😃



  • Dann muss es an Deinem Original Bitmap liegen!!! ( ? ? ? )

    Das muss den gleichen Wert haben bei Pixelformat!

    Idee:

    Erzeuge noch ein Graphics::TBitmap *tempBM=new ....;
    setze PixelFormat auf pf24bit;
    'Lade' das Bild mit tempBM->Assign(Image1->Picture);

    Mach die Umwandlung von dem tempBM ausgehend! (nicht von Image1-> ...)

    PS:
    Vergiss am Ende nicht delete tempBM;!!!



  • Auch das TmpBM hat nicht geholfen.

    Hab sowieso mit mehreren Bildern getestet. Jetzt hab ich noch einige dazu genommen. Immer das gleiche NON-Ergebnis.

    Am internen DDB-Format kann das doch nicht liegen? Ob ich an ein anderes Image oder an eine Speicherbitmap Assign()'e, das interne Handling wird nicht mit übergeben. --- Oder könnte doch irgendeine Info übergeben werden?...


Anmelden zum Antworten