简体   繁体   English

使用指针和 offsetof() 访问结构的正确方法是什么

[英]What is correct way to access a struct using pointer and offsetof()

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;最终指针计算的正确咒语是什么*(ptr + offset) = data; because I always get:因为我总是得到:

error: incompatible types when assigning to type 'struct osc_in_data' from type 'int32_t' {aka 'int'}错误:从类型 'int32_t' {aka 'int'} 分配给类型 'struct osc_in_data' 时类型不兼容

#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* .成员具有int32_t类型,因此指向它们的指针是int32_t*

The offsetof(...) is just the offset in bytes. offsetof(...)只是以字节为单位的偏移量。 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.然后使用普通加法将偏移量添加到指针,并记住使用char*指针一次添加一个字节。 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;
    }
} 

The offsetoff function tells you the distance in bytes between 2 memory adresses inside the same structure.偏移量offsetoff告诉您同一结构内 2 个 memory 地址之间的字节距离。

With below code you are telling,用下面的代码你告诉,

   *(ptr + offset) = data;

do pointer arithmetic on struct osc_in_data pointer, that is same as ptr[offset] = data;struct osc_in_data指针进行指针运算,与ptr[offset] = data;

Instead what you can try is.相反,您可以尝试的是。

memcpy((char *)ptr + offset, data, sizeof data);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM