Forum: Mikrocontroller und Digitale Elektronik Ein Array aus einem typedef auslesen


von ingo (Gast)


Lesenswert?

Guten Morgen,

ich habe folgendes typedef:

typedef struct  {
  char  dev_id;
  uint8_t  *name;
  uint8_t  *unit;
  uint8_t  *info;
  uint8_t  *sw_version;
  void  *values;
} devices_struct_t;

und folgende deklaration:

devices_struct_t devices[7];
uint8_t values0[] = {1,200,33,24,25,24,28,29,10,0};

so sieht das dann zum Beispiel für devices[0] aus:

  devices[0].dev_id = 0x00;
  devices[0].info = "Isch geb de speed an";
  devices[0].name = "Tachometer";
  devices[0].sw_version = "007";
  devices[0].unit = "km/h";
  devices[0].values = &values0;

nun möchte ich in der gleichen datei auf den ersten Wert von values 
zugreifen.

Wie geht das?
Stocher hier im drüben und erreiche nur Mist;


Danke und Gruß

Ingo

von Oops (Gast)


Lesenswert?

Ich weiss ja nicht genau wo hier das Problem ist, aber versuch doch mal
1
devices[0].values[0]

nachdem Du
1
  void  *values;
 in
1
uint8_t *values;
 geändert hast.

Gruss
Oops

von Karl H. (kbuchegg)


Lesenswert?

ingo wrote:

>   void  *values;
> } devices_struct_t;
>
> und folgende deklaration:
>
>   devices[0].values = &values0;
>
> nun möchte ich in der gleichen datei auf den ersten Wert von values
> zugreifen.
>
> Wie geht das?

Indem du zunächst mal aus dem void Pointer in der Struktur einen
Pointer machst, mit dem du auch Lese/Schreib Operationen
machen kannst.

Ein void Pointer ist ja sowas wie ein generischer Pointer.
Kein Mensch weiss, worauf er wirklich zeigt, wenn er nur
den Pointer an sich hat. Auch der Compiler weiss das nicht
und daher weiss er auch nicht, ob er jetzt bei derefernzieren
des Pointer ein einzelnes Byte oder ein Word oder sonstwas
von dort holen soll.

   uint8_t value = ((uint8_t*)devices[0].values)[0];

Holt das 0.te Byte aus dem value Array von devices[0]

Wenn du in diesem values-'Array' immer uint8_t speicherst,
solltest du auf den void Pointer komplett verzichten, und
den gleich als uint8_t Pointer ausführen: Say what you mean


typedef struct  {
  char  dev_id;
  uint8_t  *name;
  uint8_t  *unit;
  uint8_t  *info;
  uint8_t  *sw_version;
  uint8_t  *values;
} devices_struct_t;

von Boxi B. (boxi)


Lesenswert?

also, values0 ist ja bereits ein pointer auf dein array.

wenn du aber bei der belegung von
1
devices[0].values
1
&values0
angibst, klappt das nicht.

es müßte also
1
devices[0].values = values0;
heißen.

Dann kannst du mit
1
devices[0].values[0]
 an des gewünschte element rankommen.

von ingo (Gast)


Lesenswert?

Ersteinmal für euren schnellen tip.



Da ich auf einem ARM programmiere habe ich anstatt uint8_t einmal 
uint32_t gemacht.

typedef struct  {
  char  dev_id;
  uint8_t  *name;
  uint8_t  *unit;
  uint8_t  *info;
  uint8_t  *sw_version;
  uint32_t  *values;
} devices_struct_t;


Schon kommt aber die Warnmeldung  in der Zeile:

devices[0].values = &values0;

die da lautet:

assignment from incompatible pointer type

darauf hin habe ich gecastet:

  devices[1].values = (uint32_t) &values1;

darauf hin kommt die Warnung:

assignment makes pointer from integer without a cast

Genau wegen diesen Fehlermeldungen hatte ich mich dann auf einen void 
Zeiger geeinigt, aber das war auch keine clevere Wahl.

Habt ihr dafür auch noch einen Tip?

Danke und Gruß

Ingo

von Boxi B. (boxi)


Lesenswert?

ja, siehe mein post über deinem letzten

von ingo (Gast)


Lesenswert?

Hallo Boris,

das geht leider nicht!
folgende Meldung kommt bei der Zeile:

    k = devices[left].values[i];

Meldung:

warning: dereferencing 'void *' pointer
error: void value not ignored as it ought to be

von Karl H. (kbuchegg)


Lesenswert?

ingo wrote:
> Ersteinmal für euren schnellen tip.
>
>
>
> Da ich auf einem ARM programmiere habe ich anstatt uint8_t einmal
> uint32_t gemacht.

Oh. Mann.
Du sollst nicht einfach wahllos irgendeinen Pointer Typ
nehmen und hoffen, das das funktioniert.

Wenn du an den Pointer auf uint8_t Zeigen lassen willst,
dann schreib das auch so. "Say what you mean"

>
> Habt ihr dafür auch noch einen Tip?

Ja.
Pointer sind nicht gleich Pointer. Teil des Datentyps
eines Pointers ist auch der Typ der Daten auf die
er zeigt.
Ein uint8_t* ist etwas anderes als ein uint16_t*
Einfach deswegen, weil der eine auf uint8_t zeigt
und der andere auf uint16_t

Der Compiler muss doch wissen, was er bei einer Dereferenzieraktion
machen soll. Soll er ein Byte holen oder doch 2? Oder zeigt
der Pointer ev. sogar auf eine Struktur und es müssen viele
Bytes umkopiert werden? Diese Information holt sich der Compiler
aus dem exakten Typ des Pointers. Und daher ist ein uint8_t*
etwas anderes als ein uint16_t* oder ein uint32_t*

von Karl H. (kbuchegg)


Lesenswert?

ingo wrote:
> Hallo Boris,
>
> das geht leider nicht!
> folgende Meldung kommt bei der Zeile:
>
>     k = devices[left].values[i];
>
> Meldung:
>
> warning: dereferencing 'void *' pointer

Siehe meine Antwort weiter oben

von Oops (Gast)


Lesenswert?

oops, Boxi liegt richtig. Ich hatte das & ignoriert.
values0 ist ja schon der Vektorname. Davon kann man nicht noch die 
Adresse bilden. Er selbst ist schon die Adresse.

Gruss
Oops

von ingo (Gast)


Lesenswert?

Danke Jungs,

ich habs!

Ingo

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.