linux源代码中带有方法的结构体

fja*_*han 5 c linux-kernel

我正在阅读 android 内核代码,我正面临这种数据结构,

static const struct file_operations tracing_fops = {
.open       = tracing_open,
.read       = seq_read,
.write      = tracing_write_stub,
.llseek     = tracing_seek,
.release    = tracing_release,
};
Run Code Online (Sandbox Code Playgroud)

有人可以一般地解释这种语法吗?等式的右边是函数名称,&tracing_fops 稍后作为参数传递给另一个初始化 debugfs 文件系统的函数。

Bis*_*iyo 4

该赋值是使用复合文字的示例。根据C99 第 #6.5.2.5 节

由带括号的类型名称后跟大括号括起来的初始化列表组成的后缀表达式是复合文字。它提供一个未命名的对象,其值由初始值设定项列表给出。

在更简单的版本中,根据GCC 文档:复合文字

复合文字看起来像大括号括起来的聚合初始值设定项列表的强制转换。它的值是一个在强制转换中指定类型的对象,包含在初始化器中指定的元素。与强制转换的结果不同,复合文字是左值。ISO C99 及更高版本支持复合文字。作为扩展,GCC 在 C90 模式和 C++ 中也支持复合文字,尽管如下所述,C++ 语义有些不同。

一个简单的例子:

struct foo { int x; int y; };

func() {
    struct foo var = { .x = 2, .y = 3 };
    ...
}
Run Code Online (Sandbox Code Playgroud)

在问题的示例中, 是在include/linux/fs.hstruct file_operations中定义的,并且位于Linux 源代码树中的kernel/trace/trace.c文件中。tracing_fops

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 *);
...
};
Run Code Online (Sandbox Code Playgroud)

, open,read函数指针,它们是指向函数的指针write。解引用函数指针后,就可以像普通函数调用一样使用了。结构是类型。函数指针成员的值使用复合文字分配给同一文件中的函数。tracing_fopsfile_operationstrace.c

使用复合文字,我们不必显式指定/分配结构类型中的所有成员,因为其他成员设置为零或 null。使用复合文字创建的结构对象可以传递给函数,而不依赖于成员顺序。双方的函数参数应该相同。例如,参数

int (*open) (struct inode *, struct file *);
Run Code Online (Sandbox Code Playgroud)

int tracing_open(struct inode *inode, struct file *file);
Run Code Online (Sandbox Code Playgroud)

在面向对象编程中,这个思想有点类似于虚函数表