Forum: Compiler & IDEs passing struct by reference


von berliner (Gast)


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 User
von Carl D. (jcw2)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


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)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.