コールバック関数3:C言語でのコールバック関数の使用

6917 ワード

オープンソースcプロジェクトではコールバック関数があまりにもよく使われており、コールバック関数と一般関数の違いがよく分からない.機会を見つけてまとめましょう.
アレイポインタ
C言語の核心の一つはポインタであり,ポインタを理解することが重要である.まず面白いものをください.
int *p1[10] //    
int (*p1)[10]   //    

これは理解に難くないが,式1ではp 1と後[10]が結合して配列の定義となり,前方のint*は配列を表す要素がintを指すポインタであるためポインタ配列である.式2では*とp 1が結合してポインタの定義となり,intは配列中の要素をintとし,結合して配列を指すポインタを表す.一般的なポインタの定義に従って、配列ポインタをこのように定義できるかもしれません.**int(*)[10]p 2**上記の式のコンパイラは認識できないことは明らかであり、便宜上、コンパイラはp 2を前述した.ここでは、後続の関数ポインタを敷く方法を簡単に紹介します.
関数ポインタ
コールバック関数に触れる前に、関数ポインタを理解しておきます.関数ポインタは関数を指すポインタです.
char *(*fun1)(char *p1, char *p2);
char **fun1(char *p1, char *p2);
char *fun1(char *p1, char *p2);

明らかに式1だけが関数ポインタであり,配列ポインタの基礎があればこれを理解するのは難しくないはずである.
コールバック関数
簡単に言えば、関数のエントリアドレスを関数ポインタに渡し、関数ポインタを介してこの関数を呼び出すと、この関数をコールバック関数と呼ぶ.コールバック関数の一般的な使用方法は、Aが構造体の定義(メンバーにコールバック関数のポインタを含む)を行い、Bが構造体変数を宣言し、Aにコールバック関数を登録することです.Aは、ある特定のイベントがトリガーされたときに、登録されたコールバック関数をすべて巡回して実行します.次のコードは、単純なコールバック関数のルーチンです
#include 

struct operation {
    void (*callback)();
};

void trigger(struct operation* ops, int ops_length) {
    int i = 0;
    while(i++ < ops_length) {
        ops->callback();
        ops++;
    }
}
    
void a_callback() {
    printf("I'm A
"); } void b_callback() { printf("I'm B
"); } int main(int argc, char* argv[]) { struct operation A,B; A.callback = &a_callback; B.callback = &b_callback; struct operation ops[2]; ops[0] = A; ops[1] = B; trigger(ops, 2); return 1; }

A,Bはそれぞれoperationにそれぞれコールバック関数を登録している.