Simples C cast von einem Buffer in einen anderen Typ

Gast #4892043
Lesenswert?

Ich erhalte in netbuf[130] Daten und die ersten Bytes stellen den header 
dar.

Ich möchte nichts umkopieren, sondern jeglich nur auf das erste Byte des 
Buffers zugreifen können mit:

net_header_t x;

x.command = 1;


Gibt es da ein cast wie:

x = (net_header_t)netbuf;

1
typedef struct __attribute__((__packed__))
2
{
3
    uint8_t command;
4
    union
5
    {
6
        uint8_t val;
7
        struct
8
        {
9
        uint8_t direction : 1;
10
        uint8_t ack_ok : 1;
11
        uint8_t ack_error : 1;
12
        uint8_t rsvd : 5;
13
        } bits;
14
    } status;
15
} net_header_t;
16

17
static uint8_t netbuf[130];
Gast #4892060
Lesenswert?

Ich benutze so eine structur :
1
typedef struct {
2
    union {
3
        uint8 rawdata[SYSTEMMEMORYSIZE];
4
        struct {
5
            uint32  UniqueIdSlaveArray32[2];
6
            uint16  EswVersion;
7
        } vars;
8
    } system;
9
    union {
10
        uint8 rawdata[EEPROMMEMORYSIZE];
11
        struct {
12
            uint16  crc;
13
            uint16  SlaveDebugCode;
14
            uint32  CalTemp[CALPOINTSMAX][TEMPCHANNELSEXCLREF]; 
15
            uint32  CalOffset[CALPOINTSMAX][TEMPCHANNELSEXCLREF];
16
            uint16  SlaveAddress; // 0xBB10/0xBB12/0xBB14/0xBB16. Others invalid
17
        } vars;
18
    } eeprom;
19
} t_var;
20
extern t_var var;
Nur aufgepasst : Zwischen GCC und CodeVision compiler gibt es da kleine 
unterschiede in definitionen. Bin nicht mehr sicher was das war. Und man 
musz noch rechnen mit Endianess von input bytes und prozessor selber. 
Diese beispiel benutze ich am PSOC3 prozessor.

https://en.wikipedia.org/wiki/Endianness
Gast #4892070
Lesenswert?

Achim, ideal die Idee mit dem Pointer.


Funzt genau wie ich es wollte.


Jetzt wo wir gerade bei Pointern sind, vielleicht kann einer Licht ins 
Dunkle bringen..

Immer wieder frage ich mich aber worin der Unterscheid zwischen den 
Schreibweisen ist:


x->status.bits.ack_ok = 1;  (x ist der pointer auf status.bits.ack_ok)
x.status.bits.ack_ok = 1; (hier ist kein pointer im spiel, direkter 
zugrif auf ein member eines structs)

x->status->bits.ack_ok = 1;  ??
x.status.bits->ack_ok = 1;   ??
Gast #4892087
Lesenswert?

Warum zeigt er auf eine falsche Addresse,
wenn ich netbuf[130] ein static davor setze?

.oO(Wenn man bedenkt das netbuf sogar per DMA immer erreichbar ist)

1
net.c
2

3
static uint8_t netbuf[130];
4

5

6
static void  process_Rx(void)
7
{
8
    uint8_t x;
9
    net_header_t *nh;
10
    
11
    nh = (net_header_t*) netbuf;
12
    x = nh->command;
13
}
Gast #4892099
Lesenswert?

na super, jetzt bekomme ich das nicht mehr hin das er auf eine falsche 
Addresse zeigt :-)

Es ist ein PIC24F und ich habe in MPLABX gesehen das er auf eine falsche 
addresse zeigte und dazu natürlich auch die falschen werte drinne hatte.

Na gut, geht bestens.
Angehängte Dateien:
#4892621
Lesenswert?

Simon schrieb:
> Jetzt wo wir gerade bei Pointern sind, vielleicht kann einer Licht ins
> Dunkle bringen..
>
> Immer wieder frage ich mich aber worin der Unterscheid zwischen den
> Schreibweisen ist:
>
> x->status.bits.ack_ok = 1;  (x ist der pointer auf status.bits.ack_ok)
> x.status.bits.ack_ok = 1; (hier ist kein pointer im spiel, direkter
> zugrif auf ein member eines structs)

Das ist immer genau das gleiche:

> x->status->bits.ack_ok = 1;  ??

Hier ist x->status ein Zeiger.

> x.status.bits->ack_ok = 1;   ??

Hier ist x.status offenbar eine struct, und es wird direkt auf ein 
Member davon zugegriffen.
Gast #4892698
Lesenswert?

1
typedef struct 
2
{
3
    uint8_t command;
4
    uint8_t val;
5
} header_t;
6

7
header_t x;    /* Speicherplatz für die Struktur (Datenfeld) */
8
header_t *px;  /* Zeiger auf die Struktur. Noch zeigt der ins Nirvana */
9

10
    px=&x;     /* jetzt zeigt der Zeiger auf x */
11
    
12
    /* viele gleichwertige Arten, um command=1 zu setzen */
13
    /* Zuerst mit ".", also Datenfeld als Basis */
14
    x.command=1;
15
    (*px).command = 1;
16
    (*(&x)).command = 1;
17

18
    /* jetzt mit Zeiger auf ein Datenfeld, also -> */
19
    px->command=1;
20
    (&x)->command = 1;
21
    (&(*px))->command = 1; /* beliebig weit schachtelbar */
22

23
    /* jetzt ein paar konfuse, nur zur Verwirrung, bitte vergessen! */
24
    px[0].command=1; 
25
    0[px].command=1;
26
    0[&x].command=1;

All diese Beispiel schreiben jeweils auf das selbe command!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren