I have the following code so as to be able to access numerous fields in array of structs (I've reduced it to two for simplicity). What is the correct incantation for the final pointer calculation
*(ptr + offset) = data;
because I always get :
error: incompatible types when assigning to type ‘struct osc_in_data’ from type ‘int32_t’ {aka ‘int’}
#define NumHarmonics 10
int32_t data1;
int32_t data2;
struct osc_in_data
{
int32_t LevelAttackRate;
int64_t LevelPeakLevel;
int32_t LevelDecayRate;
} OscControl[NumHarmonics];
void SetADSRvalues(int32_t offset, int32_t data)
{
int32_t harmonic;
struct osc_in_data *ptr;
for (harmonic = 0; harmonic < NumHarmonics; harmonic++)
{
ptr = &OscControl[harmonic];
*(ptr + offset) = data;
}
}
SetADSRvalues(offsetof(struct osc_in_data, LevelAttackRate), data1)
SetADSRvalues(offsetof(struct osc_in_data, LevelDecayRate), data2)
The members have int32_t
type so pointers to them are int32_t*
.
The offsetof(...)
is just the offset in bytes. So you just take the pointer to the structure which member you want to modify. Then add to the pointer the offset using plain addition and remembering to use char*
pointers to add one byte at a time. Then just cast the pointer to proper type and dereference and access it.
void SetADSRvalues(size_t offset, int32_t data)
{
for (size_t harmonic = 0; harmonic < NumHarmonics; harmonic++) {
// take the pointer to the structure we want to modify
void *base = &OscControl[harmonic];
// arithmetic using void* pointers is invalid
// so convert to `char*` pointer before arithmetic
char *basechar = base;
// then add the offset - just plain addition
// results in the address of the member inside the struct
void *memberpnt = basechar + offset;
// the member is `int32_t`, so the pointer has to be `int32_t*`
int32_t *memberpnt_int32 = memberpnt;
// finally set the value
*memberpnt_int32 = data;
// or a oneliner version:
*(int32_t*)((char*)&OscControl[harmonic] + offset) = data;
}
}