C linux内核套接字源宏容器
我试图了解如何创建是套接字,但我遇到了我真的不明白的问题。此问题的代码如下所示:C linux内核套接字源宏容器,c,sockets,kernel,C,Sockets,Kernel,我试图了解如何创建是套接字,但我遇到了我真的不明白的问题。此问题的代码如下所示: static inline struct socket *SOCKET_I(struct inode *inode) { return &container_of(inode, struct socket_alloc, vfs_inode)->socket; //why here is -> socket } 我看到它是宏的容器,它返回一个指针。它将inode指针作为参数 减去vfs\
static inline struct socket *SOCKET_I(struct inode *inode)
{
return &container_of(inode, struct socket_alloc, vfs_inode)->socket; //why here is -> socket
}
我看到它是宏的容器,它返回一个指针。它将inode
指针作为参数
减去vfs\u inode
字节数
我的问题是:
为什么在宏的末尾有类似于->socket
的东西,以及它的作用是什么?inode
是socket\u alloc
结构的vfs\u inode
成员<代码>容器\u的
扩展到包含该成员的结构
该结构还包含一个socket
成员,该函数返回该成员的值
换言之,有一种结构
struct socket_alloc {
// ... some members
struct inode vfs_inode;
// ... other members
struct socket socket
// ... more members
} some_variable;
如果您这样做:
struct inode *i = &(some_variable.vfs_inode);
那你以后就可以做了
struct socket *this_sock = SOCKET_I(i);
为了获得相应的
套接字代码的指针,这有助于我更好地理解内核linux中的代码,有一个类似于sock\u alloc\u inode的函数,它返回&ei->vfs\u inode nad,我认为socket.c中包含宏的linux内核场景可能是这样的。我不确定它是否正确,但看起来很好
#include <stdio.h>
#include <stdlib.h>
#define offsetof(type, member) ((size_t) &((type *)0)->member)
#define container_of(ptr, type, member) ({ \
const typeof ( ((type *)0)->member ) *__mptr = (ptr); \
(type *) ( (char *)__mptr - offsetof(type, member) ); })
struct inode{
int a;
int b;
};
struct socket{
int some_other_data;
int this_data;
};
struct socket_alloc{
struct socket socket ;
struct inode vfs_inode;
};
static inline struct socket *SOCKET_I(struct inode *inode)
{
return &container_of(inode, struct socket_alloc, vfs_inode)->socket;
}
static inline struct inode *SOCK_INODE(struct socket *socket)
{
return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
}
int main()
{
struct inode *inode;
struct socket* socket;
struct socket_alloc *ei;
ei = (struct socket_alloc*)malloc(sizeof(*ei));
inode = (struct inode*)malloc(sizeof(*inode));
socket = (struct socket*)malloc(sizeof(*socket));
printf("INODE POINTER NO MACRO AND WITHOUT REFER TO THE SOCKET_ALLOC STRUCT %d\n", *inode);
inode= &ei->vfs_inode;
printf("INODE POINTER NO MACRO %d\n", *inode);
printf("SOCKET POINTER NO MACRO%d\n", *socket);
socket = SOCKET_I(inode);
inode = SOCK_INODE(socket);
printf("INODE POINTER USING MACRO %d\n", *inode);
printf("SOCKET POINTER USING MACRO %d\n", *socket);
free(ei);
return 0;
}
#包括
#包括
#定义偏移量(类型,成员)((大小)和((类型*)0)->成员)
#定义(ptr,type,member)({\
常量typeof(((type*)0)->成员)*\uu mptr=(ptr)\
(类型*)((字符*)u mptr-offsetof(类型,成员));})
结构节点{
INTA;
int b;
};
结构套接字{
输入一些其他数据;
把这个数据整型;
};
结构套接字\u alloc{
结构套接字;
结构索引节点vfs_索引节点;
};
静态内联结构套接字*socket\u I(结构索引节点*inode)
{
返回和容器(inode、struct socket、vfs inode)->socket;
}
静态内联结构inode*SOCK\u inode(结构套接字*socket)
{
返回和容器(socket、struct socket、alloc、socket)->vfs inode;
}
int main()
{
结构inode*inode;
结构套接字*socket;
结构套接字\u alloc*ei;
ei=(结构套接字_alloc*)malloc(sizeof(*ei));
inode=(结构inode*)malloc(sizeof(*inode));
套接字=(结构套接字*)malloc(sizeof(*socket));
printf(“INODE指针无宏且未引用套接字\u ALLOC结构%d\n”,*INODE);
inode=&ei->vfs\u inode;
printf(“INODE指针没有宏%d\n”,*INODE);
printf(“套接字指针没有宏%d\n”,*SOCKET);
插座=插座I(inode);
inode=SOCK_inode(socket);
printf(“使用宏%d\n的索引节点指针,*索引节点”);
printf(“使用宏%d\n的套接字指针,*SOCKET”);
免费(ei);
返回0;
}
“为什么宏末尾有类似于->socket
的东西,以及它的作用?”-->socket
不是宏调用的一部分。假设宏返回一个指针(类型为inode*
),您将该返回值命名为inode\u object
。因此,您可以将返回语句编写为&inode\u object->socket
。也就是说,这只是一个指向socket
字段的指针。因此,此宏将返回指向socket结构的inode指针。它将指针指向inode并减去vfs_inode字节数,然后该指针指向套接字?。我是对的?如果“vfs\u inode
bytes”是指vfs\u inode
结构中socket\u alloc
字段的偏移量,那么是的,container\u of
从输入指针中减去给定的量,并返回减法结果,并将其转换为struct socket\u alloc*
。关于这个输入指针,我还有一个问题。正如我所知,指针有一些地址和SOCKET_,我用一些地址获取指针,然后从字节中减去这个地址。然后按你说的返回插座。它怎么知道这个地址字节数将是struct socket_alloc*。我的意思是,在不设置该指针的情况下,它指向vfs\u inode/这是SOCKET\u I
函数的使用要求,只应使用inode
参数调用它,该参数指向某些SOCKET\u alloc
对象的字段vfs\u inode
。您可能想知道,如果不使用指向对象的指针,如何获得指向对象字段的指针。但实际上,在用于面向对象编程(OOP)的Linux内核中,这是非常常见的场景,当使用指向基类型对象的指针调用虚拟方法时,在这个派生类型方法的实现中,您需要将这个指向基类型的指针转换为指向派生类型的指针我想知道它为什么会工作,我的意思是如果inode是一些随机地址和宏减这个地址和vfs_inode的字节数,它怎么知道vfs_inode的随机地址偏移将指向套接字。我的意思是它怎么知道vfs_inode宏的随机地址偏移将指向结构socket_alloc,这将指向此套接字的结构套接字_allocstructureoffsetof
告诉您从结构开头到成员的字节数。因此,如果有一个指向成员的指针并减去偏移量,则会得到一个指向结构开头的指针。