Forum: Compiler & IDEs Simples C cast von einem Buffer in einen anderen Typ


von Simon (Gast)


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];

von A. S. (Gast)


Lesenswert?

1
net_header_t *ph;
2
3
   ph = (net_header_t *) netbuf;
4
5
   ph->command = 1;
6
7
/* alternative */
8
#define x (*((net_header_t *) netbuf))
9
10
   x.command = 1;

von Paddy (Gast)


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

von Simon (Gast)


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;   ??

von Simon (Gast)


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
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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

Wie diagnostizierst Du das, daß "er" auf eine falsche Adresse zeigt?

von Simon (Gast)


Angehängte Dateien:

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.

von Dirk B. (dirkb2)


Lesenswert?

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

x->y ist eine andere Schreibweise (syntaktischer Zucker) für (*x).y
Da ist x ein Zeiger auf eine struct.

Da auch Zeiger auf struct Member einer struct sein können, bekommst du 
dann mehrmals eine Dereferenzierung.

von Rolf M. (rmagnus)


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.

von A. S. (Gast)


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!

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.