Help us understand the problem. What is going on with this article?

コールバック関数とは

More than 3 years have passed since last update.

■ コールバック関数とは

他の関数に引数として渡す関数のこと。

下記サイトのC言語の例が分かりやすい。
関数ポインタにコールバック関数を代入し、引数として渡している。

http://shiroibanana.blogspot.jp/2012/09/callback.html

#include<stdio.h>
typedef void (* FUNC_POINTER)(char *); 

// コーバック関数1
void callback1(char *s){
    printf("%s\n",s);
}

// コールバック関数2
void callback2(char *s){
    printf("[");
    printf("%s",s);
    printf("].\n");
}

// コールバック関数を呼び出す関数
void func(char *s,FUNC_POINTER p){
    // コールバック関数を呼び出す
    p(s);
}

int main(){
    FUNC_POINTER p;

    p = callback1;
    // コールバック関数1を呼び出す
    func("コーバック関数1",p);

    p = callback2;
    // コールバック関数2を呼び出す
    func("コーバック関数2",p);
    return 0;
}

実行結果。

コーバック関数1
[コーバック関数2].

■ Pythonの例

pythonでのコールバック関数の使用例。
コールバック関数を呼び出す関数はhandlerと記述されることが多いらしい↓

def handler(func,*args):
    return func(*args)

http://www.phactory.jp/cms/blog/post/admin/2010/02/python_funcpointer/

流れとしては、

  1. ハンドラーを定義
  2. コールバック関数を定義
  3. 関数ポインタにコールバック関数を代入
  4. 関数ポインタをハンドラーの引数として渡す
# -*- coding: utf-8 -*-
def handler(func,*args):
    return func(*args)

def callback1(message1):
    print("%s" % message1)

def callback2(message1, message2):
    print("%s, %s" % ( message1, message2) )

# main
if __name__ == "__main__":

   # コールバック関数の代入
   call = callback1
   # ハンドラーの実行 : コールバック関数の呼び出し
   handler(call, "message1")

   # コールバック関数の代入
   call = callback2
   # ハンドラーの実行 : コールバック関数の呼び出し
   handler(call, "message1", "message2")

実行結果。

message1
message1, message2

■ クラスを使う

関数ポインタの役割をする変数をクラス内のメンバ"func"に持たせているが、基本的にやってることは同じ。

  1. ハンドラーとして機能するクラスを定義
  2. 関数ポインタとして扱うメンバを定義
  3. ハンドラーとして機能するメソッドを定義
  4. コールバック関数を定義
  5. 関数ポインタにコールバック関数を代入
  6. 関数ポインタをハンドラーの引数として渡す
# -*- coding: utf-8 -*-
class Callbacker():
    def __init__(self, func):
        self.func = func

    def handler(self, *args):
        self.func(*args)

def callback1(message1):
    print '%s' % message1

def callback2(message1, message2):
    print("%s, %s" % ( message1, message2) )

# main
if __name__ == "__main__":

    # コールバック関数の代入
    callback = Callbacker(callback1)
    print (type(callback.func))
    print ("callback.func "),
    print (callback.func)
    print ("callback1     "),
    print (callback1)
    # ハンドラーの実行 : コールバック関数の呼び出し
    callback.handler("message1")
    print ("")

    # コールバック関数の代入
    callback.func = callback2
    print (type(callback.func))
    print ("callback.func "),
    print (callback.func)
    print ("callback2     "),
    print (callback2)
    # ハンドラーの実行 : コールバック関数の呼び出し
    callback.handler("message1", "message2")

実行結果

<type 'function'>
callback.func  <function callback1 at 0x7fcff9c8a9b0>
callback1      <function callback1 at 0x7fcff9c8a9b0>
message1

<type 'function'>
callback.func  <function callback2 at 0x7fcff9c8ab18>
callback2      <function callback2 at 0x7fcff9c8ab18>
message1, message2

■ まとめ

コールバック関数とは他の関数に引数として渡す関数のこと。

基本は、
1. ハンドラーを定義
2. コールバック関数を定義
3. 関数ポインタにコールバック関数を代入
4. 関数ポインタをハンドラーの引数として渡す

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした