Использование структур для установки функций - PullRequest
0 голосов
/ 27 декабря 2011

При написании модулей / драйверов ядра большую часть времени некоторые структуры инициализируются так, чтобы указывать на некоторые конкретные функции.Как новичок в этом может кто-то объяснить важность этого.

Я видел struct file_operations во время написания драйвера символьного устройства

Также я обнаружил, что даже если функции объявлены, они не реализованывсегда.Может ли кто-нибудь помочь в этом тоже.Например, в источнике ядра: kernel / dma.c, определены события eventhough

static const struct file_operations proc_dma_operations = {
    .open       = proc_dma_open,
    .read       = seq_read,
    .llseek     = seq_lseek,
    .release    = single_release,
};

, реализован только proc_dma_open.

Ответы [ 3 ]

1 голос
/ 28 декабря 2011

Функции seq_read, seq_lseek и single_release объявлены в исходном файле ядра linux-3.1.6/include/linux/seq_file.h и определены в исходном файле ядра linux-3.1.6/fs/seq_file.c.Они, вероятно, являются общими для многих файловых операций.

1 голос
/ 27 декабря 2011

Если вы когда-либо играли с объектно-ориентированными языками, такими как C ++, представьте, что file_operations - это базовый класс, а ваши функции - реализации его виртуальных методов.

0 голосов
/ 27 декабря 2011

Указатели на функции - очень мощный инструмент на языке Си, который позволяет в реальном времени перенаправлять вызовы функций. Большинство, если не все операционные системы имеют похожий механизм, как, например, печально известные функции INT 21 25/35 в старой MS-DOS, которые позволяли существовать программам TSR.

В C вы можете назначить указатель на функцию переменной и затем вызвать эту функцию через эту переменную. Функция может быть изменена либо во время инициализации на основе некоторых параметров, либо во время выполнения на основе некоторого поведения.

Вот пример:

int fn(int a)
{
   ...
   return a;
}

...

int (*dynamic_fn)(int);
...
dynanic_fn = &fn;
...
int i = dynamic_fn(0);

Когда указатель «живет» в структуре, которую можно передать системным вызовам, это очень мощная функция, позволяющая подключаться к системным функциям.

В объектно-ориентированных языках такого же поведения можно добиться, используя отражение для динамического создания классов.

...