Я предполагаю, что вы сначала загружаете модуль B, а затем опционально модуль A. Моя стратегия заключается в том, чтобы при первой инициализации A регистрировать набор функций с помощью B.B хранит статически размещенный указатель на функцию (или указатель на структуру, полную указателей на функции) и предоставляет экспортированные функции для регистрации и отмены регистрации обработчика.Когда A загружается, он регистрирует свою функцию (или структуру функций) с B. Когда A выгружается, он отменяет регистрацию своих функций.
Это может выглядеть примерно так:
Bh
typedef int (*foo_t)(int);
int B_register_foo(foo_t);
int B_unregister_foo(foo_t);
Bc
static foo_t foo = NULL;
int B_register_foo(foo_t f) {
if (!foo) {
foo = f;
return 0;
}
return -EFOO;
}
void B_unregister_foo(foo_t f) {
if (foo == f)
foo = NULL;
}
EXPORT_SYMBOL(B_register_foo);
EXPORT_SYMBOL(B_unregister_foo);
void B_maybe_call_foo(int arg) {
return (foo) ? foo(arg) : 0;
}
Ac
static int A_foo(int arg);
static int __init init_A(void) {
if (B_register_foo(A_foo))
return -EFOO;
return 0;
}
static void __exit exit_A(void) {
B_unregister_foo(A_foo);
}