01🙆♂️起因
在学习字符设备驱动的时候,看到Linux内核中的结构体的指定初始化方式(designated initializer)使用方式,之前没有见过这种初始化形式,做一点探索。
/* 字符设备操作集 */
static struct file_operations gpio_fops={
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_relase,
.read = gpio_read,
.write = gpio_write,
.fasync = gpio_fasync,
.release = gpio_release,
};
上面的结构体,
-
通过
.open = gpio_open,的方式,进行初始化结构体的成员项。 -
将驱动注册到内核中。
-
然后,应用程序使用
open的时候,直接通过回调函数的形式来执行我们驱动实现的相关功能gpio_open。
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*mremap)(struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
... // 省略
};
02🙆♂️好处分析:
- 使用灵活,可以指定某一项进行初始化,而不是将所有的成员变量来初始化。
- 代码易于维护,内核中,会有大量的代码都会使用这个
file_operations结构体来定义变量,并且初始化,如果结构体后续,需要添加成员,或者调整成员顺序,那么会引起大量的文件都要重新编译,牵一发而动全身。通过这种方式,就不用有这个但心。
03🙆♂️内存大小的变化
既然可以指定初始化结构体里面的几个变量,但结构体实例化后的内存是不是也会又变化?
答案是结构体变量,无论初始化与否,成员变量都会占用内存空间的。
测试代码如下:
#include "stdio.h"
struct student{
char name[20];
int age;
int height;
};
int main(void)
{
struct student stu1={ "01", 20, 178 };
printf("%s:%d:%d\r\n", stu1.name, stu1.age, stu1.height);
printf("stu1 size: %d\r\n", sizeof(stu1));
struct student stu2=
{
.name = "02",
.age = 28
};
printf("%s: %d\r\n",stu2.name,stu2.age);
printf("stu2 size: %d\r\n", sizeof(stu2));
return 0;
}
student结构体应该占据20+4+4个字节bytes的空间,实测如下
01:20:178
stu1 size: 28 # 初始化三个成员变量
02: 28
stu2 size: 28 # 初始化两个成员变量
* Press any key to close the terminal.
文章探讨了Linux内核中使用designatedinitializer初始化结构体成员的方式,以字符设备驱动中的file_operations结构体为例。这种方式允许灵活地初始化结构体的部分成员,提高代码可维护性,避免因结构体成员变动导致大量代码修改。尽管只初始化部分成员,结构体实例的内存大小并不会因此减少,所有成员仍会占用空间。

562

被折叠的 条评论
为什么被折叠?



