- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 9 von 9

Thema: C-Problem - Variable / Pointer als Out-Parameter einer Methode

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.05.2007
    Beiträge
    24

    C-Problem - Variable / Pointer als Out-Parameter einer Methode

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Zusammen

    Ich beschäftige mich mit einem ESP-32 und einem Display (ArduiTouch). Die Ansteuerung klappt wunderbar. Auch das Darstellen von Bildern funktioniert super.
    Ich hatte nun die Idee, dass ich die Bilder über einen Index von einer Methode bekommen kann.

    Zur Erklärung: Ich bekomme von einem Wetterdienst einen Index mitgeteilt, welches Wettersymbol heute dargestellt werden soll.
    Aus diesem Grund habe ich mir eine Methode "getImage" geschrieben, welche mir nebst dem Image auch noch die Höhe, Breite und eine Bezeichnung gibt.

    Code:
    uint16_t sonne[] PROGMEM = {
    0x0861, 0x1082, 0x10a2, 0x18c3, 0x18e3, 0x2104, 0x2124
    };
    
    uint16_t wolke[] PROGMEM = {
    0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0841
    };
    
    void getImage(int idx, int &width, int &height, String &text, uint16_t* img) {
        width = 0;
        height = 0;
        text = "";
       switch (idx) {
            case 1:
                img = sonne;
                width = 68;
                height =52;
                text = "Sonne";
                break;
            case 2:
                img = wolke;
                width = 105;
                height =51;
                text = "Wolke";
               break;
        }
    }
    
    void loop() {
          // sonstiger Code zum Holen des Indexes vom Wetterdienst, usw.
          // ...
          int idx = 1;
    
          // Passendes Bild von meiner Methode liefern lassen
         uint16_t* img;      
         int width = 0;
         int height = 0;
         String text = "";
    
    
          getImage(idx, width, height, text, img);
          
    
          // Bild zeichnen (so funktionierts, da das Bild "sonne" direkt übergeben wird und nicht aus der Methode kommt
          display.drawRGBBitmap(20, 85, sonne, height, width);
    
          // Bild zeichnen (so stürzt es ab, da mit der Variable img etwas nicht stimmt)
          display.drawRGBBitmap(20, 85, img, height, width);      
    
    
    
          // Logik für die Pause bis zum Wetterwechsel...
          // ...
    
    }
    


    Ich verstehe, dass ich irgendein Problem mit der Variable / Pointer "img" mache. Ich finde nur die Lösung nicht.

    Wo muss ich ein * durch ein & oder irgendwie was anderes ersetzen :-P
    Die Variablen width, height und text werden korrekt gefüllt und können auch problemlos ausgegeben werden.

    Die Methode "drawRGBBitmap" der Adafruit GFX-Library hat folgende Signatur:
    Code:
    void drawRGBBitmap(int16_t x, int16_t y, uint16_t *pcolors, int16_t w, int16_t h);
    
    //@param x Top left corner horizontal coordinate.  //@param y Top left corner vertical coordinate.  //@param pcolors Pointer to 16-bit array of pixel values.  //@param w Width of bitmap in pixels.  //@param h Height of bitmap in pixels.

    Ich hoffe ihr versteht was ich gerne möchte und könnt mir helfen.

    Als Ausgabe beim Absturz auf dem seriellen Monitor erhalte ich folgendes:
    Code:
    Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
    Core 1 register dump:
    PC      : 0x400850e1  PS      : 0x00060630  A0      : 0x80121300  A1      : 0x3ffb1d00
    A2      : 0x3ffc0bd4  A3      : 0x00000000  A4      : 0x000000be  A5      : 0x00000000
    A6      : 0x0000000f  A7      : 0x3ff65000  A8      : 0x3ff65000  A9      : 0x00000000
    A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000030  A13     : 0x00000010
    A14     : 0x000000bc  A15     : 0x00000040  SAR     : 0x0000001c  EXCCAUSE: 0x0000001c
    EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff
    Anschliessend startet der Controller neu.



    Liebe Grüsse
    Chruttli

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    void getImage(int idx, int &width, int &height, String &text, uint16_t* img)
    Ist so "falsch".

    Du hast eine Funktion, die die Daten eines Bildes liefern soll. Der musst Du nicht die Daten des Bildes übergeben, die Funktion soll diese als Ergebnis irgendwo liefern.

    Einfachheit halber kannst Du zunächst "height" und "width" woanders definieren, sowie die andern Variablen, die mit Inhalt gefüllt werden sollen. Nicht innerhalb der Funktion "getImage", sondern außerhalb dieser. Damit Du aus andern Funktionen drauf zugreifen kannst.


    "void getImage(int idx)" wäre ausreichend.



    So weit ...


    MfG

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    02.05.2007
    Beiträge
    24
    Danke für deine Antwort.

    Ich glaube du hast mich aber falsch verstanden.
    Ich benötige von der Methode mehrere Rückgabewerte. Die Methode soll mir zu einem bestimmten Index das passende Bild, sowie dessen Grösse (diese ist bei allen Bilden unterschiedlich) und der beschreibende Text liefern.
    In C# oder Java würde ich das mit "Out"-Parametern realisieren. Ich weiss nur nicht genau wie das in C geht. Ich dachte mit dem & vor dem Variablennamen wird deklariert, dass sie quasi ByRef übergeben werden.

    Ich erhalte vom Wetterdienst: Heute ist das Wetter 1.
    Meine Methode soll mir nun anhand der Ziffer 1 ein uint16_t-Array gefüllt mit den Daten einer Sonne, mit 68px Breite und 52px Höhe, sowie den Text "Sonne" zurückliefern, damit ich dies auf meinem Display schreiben, resp. das Bild malen kann.

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Die von dir angegebene Funktionssignatur ist nicht für Progmem (Flash), sondern für RAM. Daher der Zugriffsfehler LoadProhibited. Die für dich relevante Funktion findest du hier.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    chruttli, kann passieren.

    Ich habs nur überflogen und mich über die Struktur gewundert. Daher kam das.

    Nun hast Du ja einen entscheidenden Hinweis, Betreffs des Aufbaus Deines Programms, gegeben.


    Es gibt immer verschiedene Möglichkeiten ein Programm aufzubauen.
    So verhält sich dann auch mit Objekten oder nicht Objekten. Wenn Du von Methode sprichst, bin ich da auch irritiert. Bis jetzt sehe ich nur Funktionen, ein Objekt fehlt mir noch.

    Ist bei mir schon paar Jahre länger her, aber ich habe noch in Erinnerung, dass Java rein objektorientiert ist. Dort funktioniert alles über Klassen und Methoden (s. Objekte).


    Nichts passiert, alles i.O.




    MfG
    Geändert von Moppi (21.08.2019 um 23:40 Uhr)

  6. #6
    HaWe
    Gast
    Zitat Zitat von Moppi Beitrag anzeigen
    chruttli, kann passieren.

    Ich habs nur überflogen und mich über die Struktur gewundert. Daher kam das.

    MfG
    oftmals sind Antworten, wenn man die eigentliche Frage nur "nur überflogen" hat, nicht so besonders zielführend

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Im objektorientierten C++ wäre ein Lösungsansatz die Definition eines Images (hier als Struktur).
    Danach muss dem display-Objekt noch beigebracht werden, wie Images gezeichnet werden:

    Code:
    // Definition eines Images
    struct Image {
        const int16_t width, height;
        const char* text;
        const uint16_t* data;
    };
    
    // Klasse MyTFT erweitert Adafruit_ILI9341 um Methode drawImage
    class MyTFT : public Adafruit_ILI9341 {
    public:
      void drawImage(int16_t x, int16_t y, Image i) {
        this->drawRGBBitmap(x, y, i.data, i.height, i.width);
      }
    };
    
    // Bitmaps im Flash
    uint16_t wolke_bitmap[] PROGMEM = {
    0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0841
    };
    uint16_t sonne_bitmap[] PROGMEM = {
    0x0861, 0x1082, 0x10a2, 0x18c3, 0x18e3, 0x2104, 0x2124
    };
    
    // Images erstellen
    const Image wolke = { 20, 25, "Wolke", wolke_bitmap };
    const Image sonne = { 68,  2, "Sonne", sonne_bitmap };
    
    // display-Objekt, dass mit Images umgehen kann, erstellen
    MyTFT display = MyTFT(TFT_CS, TFT_DC, TFT_RST); // Hier Pins eintragen
    
    //...
    
    void loop(){
    //...
        display.drawImage(10, 10, sonne);
    }

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    02.05.2007
    Beiträge
    24
    @Moppi: ja, ich bin beruflich Softwareentwickler und arbeite den ganzen Tag objektorientiert Deshalb meine falschen Bezeichnungen. Ich meine natürlich Funktion und nicht Methode

    @Sisor: Besten Dank für dein Beispiel. Das ist glaube ich so ungefähr das, wie ich es mir vorstelle. Ich werde es zu Hause testen.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    02.05.2007
    Beiträge
    24
    Vielen Dank euch allen für die Hilfe.

    Mit Sisor's Vorschlag funktioniert es bestens.

    Gruess
    Chruttli

Ähnliche Themen

  1. pthread-Task als Methode einer C++ Klasse?
    Von HaWe im Forum Raspberry Pi
    Antworten: 44
    Letzter Beitrag: 29.09.2016, 20:37
  2. Pointer als Parameter und Rückgabewert
    Von Bumbum im Forum C - Programmierung (GCC u.a.)
    Antworten: 11
    Letzter Beitrag: 02.12.2012, 15:11
  3. ATTiny25 _delay_ms mit Variable als Parameter
    Von Bumbum im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 19.07.2012, 23:37
  4. Variable als Parameter oder Return-Value
    Von Jaecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 31.01.2011, 14:33
  5. setzen einer Variable nach ablauf einer bestimmten Zeit
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 08.12.2008, 00:45

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen