2012-08-10 13 views
8

C'è un modo pulito di lanciare una struct in un uint64_t o qualsiasi altro int, data quella struct in < = alla sizeof int? L'unica cosa che posso pensare è solo una soluzione "ok" - usare i sindacati. Comunque non mi sono mai piaciuti.Casting struct into int

Lasciatemi aggiungere un frammento di codice per chiarire:

typedef struct { 
uint8_t field: 5; 
uint8_t field2: 4; 
/* and so on... */ 
}some_struct_t; 

some_struct_t some_struct; 
//init struct here 

uint32_t register; 

Ora come faccio io scaccio some_struct per catturare i suoi bit di ordine nel registro uint32_t.

Spero che lo renda un po 'più chiaro.

+4

C'è sempre memcpy! –

+0

@MartinBeckett Questa sarebbe una buona risposta :) – dasblinkenlight

+7

Non "affezionato" ai sindacati? Un sindacato fa esattamente ciò che vuoi fare in modo chiaro e manutenibile. Cosa c'è "OK" a riguardo? –

risposta

1

una soluzione non-portatile:

struct smallst { 
    int a; 
    char b; 
}; 

void make_uint64_t(struct smallst *ps, uint64_t *pi) { 
    memcpy(pi, ps, sizeof(struct smallst)); 
} 

Si può affrontare problemi se, per esempio, di porre lo struct su una macchina little-endian e scompattarlo su un big-endian macchina.

15

Ho appena colpito lo stesso problema, e ho risolto con un sindacato come questo:

typedef union { 
    struct { 
     uint8_t field: 5; 
     uint8_t field2: 4; 
     /* and so on... */ 
    } fields; 
    uint32_t bits; 
} some_struct_t; 

/* cast from uint32_t x */ 
some_struct_t mystruct = { .bits = x }; 

/* cast to uint32_t */ 
uint32_t x = mystruct.bits; 

HTH, Alex

0

è possibile utilizzare i puntatori e sarà facile per esempio :

struct s { 
    int a:8; 
    int b:4; 
    int c:4; 
    int d:8; 
    int e:8; }* st; 

st->b = 0x8; 
st->c = 1; 
int *struct_as_int = st; 

speranza che aiuta

+0

Ciò richiede un typecast in qualsiasi compilatore conforme, e anche su molti compilatori richiede l'uso di '-fno-strict-aliasing 'o qualche opzione simile. – supercat