mikrocontroller.net

Forum: Compiler & IDEs passing struct by reference


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von berliner (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander!

ich möchte einen Teil der Struktur, die ich als Referenz an ein 
Unterprogramm übergeben habe, an ein weiteres Unterprogramm übergeben.
Vorgestellt hab ich es mir so:

struct lsm330dlc_acc_rdg {
        uint8_t status;   // ACC Status
        uint16_t src;
        uint8_t char fss;
        uint8_t acc[3];
};

struct lsm330dlc_rdg {
       struct lsm330dlc_acc_rdg acc_rdg;
       struct lsm330dlc_gyro_rdg gyr_rdg;
};


int LSM330_read(struct acc_rdg* SensorOutput)
{
  readRegs(LSM330_ACCAddr, OUT_X_L_A, SensorOutput->acc_rdg->acc);
}

uint8_t readRegs(uint8_t deviceAddr, uint8_t reg, uint16_t* dataPtr)
{
  /* do something */
  return true;
}

Beim Compilieren mit CooCox bekomme ich jedoch die Fehlermeldung:
85: error: invalid type argument of '->' (have 'struct 
lsm330dlc_acc_rdg')

Die Treffer bei Google behandeln nur die erste Stufe der Übergabe per 
Referenz.
Kann mir jemand sagen, was ich da falsch mache?

: Verschoben durch Moderator
von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
uint16_t* ist kein uint8_t*!
aber genau das wird beim Aufruf von readRegs() versucht.

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
2 lesenswert
nicht lesenswert
Das fängt schon mal hiermit an:

> int LSM330_read(struct acc_rdg* SensorOutput)

"struct acc_rdg" ist nicht definiert. Ich vermute mal, daß Du eigentlich 
"struct lsm330dlc_rdg" meinst.

Dann geht es hiermit weiter:

> readRegs(LSM330_ACCAddr, OUT_X_L_A, SensorOutput->acc_rdg->acc);

Das Strukturelement "acc_rdg" ist kein Pointer, also kannst Du es auch 
nicht dereferenzieren. Statt -> gehört dort ein . hin.

Deine Funktion readRegs erwartet als drittes Argument einen Pointer, 
d.h. Du musst die Adresse von "acc" bestimmen und übergeben. Das ginge 
mit dem Adressoperator & -- wenn denn die Typen passen würden.

Da ist Dein drittes Problem: acc ist ein uint8_t-Array mit drei 
Elementen.

Deine Funktion "readRegs" erwartet aber einen Pointer auf uint16_t.

Das passt nicht hinten und nicht vorne.


Im übrigen grenzt Deine Namensvergabe an den Versuch der "code 
obfuscation", wenn Du etwas klarere und eindeutigere Namen verwenden 
würdest, würde Dir vielleicht der eine oder andere Knoten von selbst 
aufgehen.

von berliner (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort!

hab das jetzt so gemacht und es funktioniert:

readRegs(LSM330_ACCAddr, (OUT_X_L_A | RW_MULTIPLE_BM), 
SensorOutput->acc_rdg.acc);

Gesamtes Beispiel:


struct lsm330dlc_acc_rdg {
        unsigned char status;   // ACC Status
        unsigned char src;
        unsigned char fss;
        uint16_t acc[3];
};

struct lsm330dlc_gyro_rdg {
        unsigned char status;   // Gyro Status
        unsigned char src;
        unsigned char fss;
        uint16_t rot[3];
};

struct lsm330dlc_rdg {
       struct lsm330dlc_acc_rdg acc_rdg;
       struct lsm330dlc_gyro_rdg gyr_rdg;
};

int LSM330_read(struct lsm330dlc_rdg* SensorOutput)
{
   readRegs(LSM330_ACCAddr, (OUT_X_L_A | RW_MULTIPLE_BM), 
SensorOutput->acc_rdg.acc);
}

uint8_t readRegs(uint8_t deviceAddr, uint8_t reg, uint16_t* dataPtr)
{
   /* Do something */
}

Der Fehlerschwerpunkt war bei "SensorOutput->acc_rdg.acc". Da fehlen mir 
wohl noch ein Paar Grundlagen.

Die anderen Sachen waren Kopierfehler, beim Versuch den Code fürs Forum 
verdaulich zu machen :-)

Zu "code obfuscation" -> werde mir wohl noch die Namensconventionen für 
C anschauen müssen, wollte es erst beim Refactoring machen.

Vielen Dank nochmal für die vielen Antworten!
Gruß Stefan

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.