最初にモジュール B をロードし、次にオプションでモジュール A をロードすると仮定します。私の戦略は、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);
紀元前
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;
}
交流
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);
}