Forum: Compiler & IDEs C pointer in Struct-Array übergeben


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 RH (Gast)


Lesenswert?

Hallo,

ich habe folgendes Problem:

Ich möchte uint32_t integer Variablen in ein uint8_t Array schreiben. 
Die Variablen werden einem struct zugeordnet und bekommen dort einen 
Namen. Der Variablenwert wird als Zeiger auf die jeweilige Variable in 
der structur hinterlegt.

Das Füllen des uint8_t Arrays möchte ich nun über den in dem struct 
hinterlegten pointer machen (siehe Code).
1
struct uint32_t_variable
2
{
3
  char* name[10];
4
  uint32_t* ptr;
5
};
6
7
struct uint32_t_variable uint32_t_variablen[] =
8
{
9
    {"Zähler 1", &cnt},
10
    {"Zähler 2", &cnt2}
11
};
12
uint8_t nmbr_of_uint32_t_variables = sizeof(uint32_t_variablen)/sizeof(*uint32_t_variablen);

mit der Funktion void MP_update_array(void) möchte ich nun das Array 
tx_value_buffer updaten. wie folgt:
1
void MP_update_array(void){
2
  uint8_t *pos = tx_value_buffer;
3
  for(int i = 0; i < nmbr_of_uint32_t_variables; i++){
4
    uint32_t* value = uint32_t_variablen[i].ptr;
5
    *pos = *value >> 24;
6
    pos++;
7
    *pos = *value >> 16;
8
    pos++;
9
    *pos = *value >> 8;
10
    pos++;
11
    *pos = *value;
12
    pos++;
13
  }
14
}

Leider wird mir hier in das Array eine sehr hohe Zahl (vermutlich die 
Speicheradressen?) geschrieben. Wenn ich *pos = &cnt; anstelle von *pos 
= *value; schreibe wird mir der richtige Wert ins Array geschrieben. Das 
riecht stark nach einem Fehler in meinem struct aber was mache ich 
falsch? Ich verzweifle.

Das ganze läuft in der STM32CubeIDE auf einem STM32G0 Kern.

: Verschoben durch Moderator
von Jim M. (turboj)


Lesenswert?

STM32 ist little endian.

von z.B. (Gast)


Lesenswert?

RH schrieb:
> struct uint32_t_variable
> {
>   char* name[10];
>   uint32_t* ptr;
> };
>
> struct uint32_t_variable uint32_t_variablen[] =
> {
>     {"Zähler 1", &cnt},
>     {"Zähler 2", &cnt2}
> };

in der struct ist char* ein Array von Zeigern (und kein Stringarray - 
was die Zuweisung wohl annimmt).

von C++ ist doof (Gast)


Lesenswert?

in C
1
   uint32_t x = 0x10203040;
2
   printf("als int32-Wert: %#x\n", x);
3
4
   uint8_t* p = (uint8_t*)&x;
5
6
   uint8_t arr[4];
7
8
   for (int i = 0; i < 4; i++)
9
      arr[i] = *p++;
10
11
   uint32_t* p32 = (uint32_t*)arr;
12
13
   printf("als Array: %#x\n", *p32);

von Andreas J. (ajbln)


Lesenswert?

RH schrieb:
> uint32_t* value = uint32_t_variablen[i].ptr;
>     *pos = *value >> 24;
>     pos++;
>     *pos = *value >> 16;
>     pos++;
>     *pos = *value >> 8;
>     pos++;
>     *pos = *value;
>     pos++;

Stattdessen kannst Du auch folgendes machen:

    *reinterpret_cast<uint32_t*>(pos) = *value;
    pos += sizeof(uint32_t);

So bleibt die Endianess aber gleich! Wenn Du aber Little Endian bist und 
Big Endian rausschreiben willst wie in Deinem Code (Highbyte first), 
musst Du die Endianess vorher drehen.

Das geht z.B. so (kann aber von der Plattform abhängen):

    *reinterpret_cast<uint32_t*>(pos) = htobe32(*value);

Versuche nicht von Hand zu drehen, viele Prozessoren haben dafür 
spezielle Maschinenbefehle, daher sind solche Endianessconverter immer 
sinnvoller.
Wie gesagt, je nach Plattform können sie auch anders heißen.
Meistens irgendwas mit h(ost) to 32 bits oder unsigned integer...

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]
  • [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.