macro conatainer_of () en el kernel de Linux -
Cuando se trata de administrar varias estructuras de datos en código, casi siempre necesitará incrustar una estructura en otra y recuperarlas en cualquier momento sin que se le hagan preguntas sobre las compensaciones o límites de la memoria. Digamos que tienes una persona estructura, como se define aquí:
struct person {
int age;
int salary;
char *name;
} p;
Al tener solo un puntero sobre la edad o el salario, puede recuperar la estructura completa que envuelve (contiene) ese puntero. Como dice el nombre, la macro container_of se usa para encontrar el contenedor del campo dado de una estructura. La macro se define en include / linux / kernel.hy se parece a lo siguiente:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
No tenga miedo de los indicadores; solo véalos de la siguiente manera:
container_of(pointer, container_type, container_field);
Estos son los elementos del fragmento de código anterior:
- puntero: este es el puntero al campo en la estructura
- container_type: este es el tipo de estructura que envuelve (contiene) el puntero
- container_field: este es el nombre del campo al que apunta el puntero dentro de la estructura
Consideremos el siguiente contenedor:
struct person {
int age;
int salary;
char *name;
};
Ahora, consideremos una de sus instancias, junto con un puntero al miembro de edad:
struct person somebody;
[...]
int *age_ptr = &somebody.age;
Junto con un puntero al miembro de nombre (age_ptr), puede usar la macro container_of para obtener un puntero a toda la estructura (contenedor) que envuelve este miembro usando lo siguiente:
struct person *the_person;
the_person = container_of(age_ptr, struct person, age);
container_of tiene en cuenta el desplazamiento de la edad al comienzo de la estructura para obtener la ubicación correcta del puntero. Si resta el desplazamiento de la edad del campo del puntero age_ptr, obtendrá la ubicación correcta. Esto es lo que hace la última línea de la macro:
(type *)( (char *)__mptr - offsetof(type,member) );
Aplicando esto a un ejemplo real, da lo siguiente:
struct family {
struct person *father;
struct person *mother;
int number_of_sons;
int family_id;
} f;
[...]
int *fam_id_ptr = &f.family_id;
struct family *fam_ptr;
fam_ptr = container_of(fam_id_ptr, struct family, family_id);
La macro container_of se usa principalmente en contenedores genéricos en el kernel.
Eso es todo sobre container_of macro en el kernel.
rb_node
.