「C++の基礎 - コールバック関数」の版間の差分
		
		
		
		
		
		ナビゲーションに移動
		検索に移動
		
				
		
		
	
|  (ページの作成:「== コールバック関数とは == コールバックとは、プログラミングにおいて、他のコードの引数として渡されるサブルーチンであ…」) | 細 (文字列「</source>」を「</syntaxhighlight>」に置換) | ||
| (同じ利用者による、間の2版が非表示) | |||
| 5行目: | 5行目: | ||
| == C言語のサンプルコード == | == C言語のサンプルコード == | ||
| 下記のサンプルコードにおいて、main() -> Hello() -> Show() の順番に呼ばれる機構をコールバックと呼ぶ。<br> | 下記のサンプルコードにおいて、main() -> Hello() -> Show() の順番に呼ばれる機構をコールバックと呼ぶ。<br> | ||
|   < |   <syntaxhighlight lang="c++"> | ||
|   // main.c |   // main.c | ||
|   #include <stdio.h> |   #include <stdio.h> | ||
| 27行目: | 27行目: | ||
|      printf("Hello World!!"); |      printf("Hello World!!"); | ||
|   } |   } | ||
|   </ |   </syntaxhighlight> | ||
| <br><br> | <br><br> | ||
| == C++言語のサンプルコード == | == C++言語のサンプルコード == | ||
| 下記のサンプルコードにおいて、CInvoker::Executeを呼び出すことでCInvoker::CallbackFuncがコールバックされる。<br> | 下記のサンプルコードにおいて、CInvoker::Executeを呼び出すことでCInvoker::CallbackFuncがコールバックされる。<br> | ||
|   < |   <syntaxhighlight lang="c++"> | ||
|   // CInvoker.h |   // CInvoker.h | ||
|   class CInvoker |   class CInvoker | ||
| 70行目: | 70行目: | ||
|      return clsInvoker->m_Data; |      return clsInvoker->m_Data; | ||
|   } |   } | ||
|   </ |   </syntaxhighlight> | ||
| <br><br> | <br><br> | ||
2021年11月22日 (月) 19:44時点における最新版
コールバック関数とは
コールバックとは、プログラミングにおいて、他のコードの引数として渡されるサブルーチンである。
これにより、低レベルの抽象化層が高レベルの層で定義された関数(サブルーチン)を呼び出せるようになる。
C言語のサンプルコード
下記のサンプルコードにおいて、main() -> Hello() -> Show() の順番に呼ばれる機構をコールバックと呼ぶ。
 // main.c
 #include <stdio.h>
 
 void Hello(void (fnShow)(void));
 void Show(void);
 
 int main()
 {
    Hello(Show);
    return 0;
 }
 
 void Hello(void (fnShow)(void))
 {
    fnShow();
 }
 
 void Show(void)
 {
    printf("Hello World!!");
 }
C++言語のサンプルコード
下記のサンプルコードにおいて、CInvoker::Executeを呼び出すことでCInvoker::CallbackFuncがコールバックされる。
 // CInvoker.h
 class CInvoker
 {
    private:
       int m_Data;
  
    pubic:
       CInvoker();
       ~CInvoker();
       void Execute();
       static int CallbackFunc(void* userData); // コールバック関数
 }
 
 // CInvoker.cpp
 // コンストラクタ
 CInvoker::CInvoker() : m_Data(100)
 {
 }
 
 // デストラクタ
 CInvoker::~CInvoker()
 {
 }
 void CInvoker::Execute()
 {
    int result = 0;
    result = reinterpret_cast<CInvoker*>(this)->CallbackFunc(this);
 }
  
 // コールバック関数
 int CInvoker::CallbackFunc(void* clsObject)
 {
    CInvoker clsInvoker = reinterpret_cast<CInvoker*>(clsObject);
 
    return clsInvoker->m_Data;
 }
仕組み
C++のクラスでコールバックメソッドを実行するには静的(static)なメソッドにしなければならない。
静的(static)でないと、以下のコンパイルエラーが表示される。
仮想関数のアドレスを取ろうとしました
これは、クラスが生成されるまでメモリ上に展開されず、呼び出し元のメソッドがどのポインタを参照すればよいかわからないためエラーになる。
即ち、静的メソッドにしてポインタの位置を固定した後、reinterpret_castでアドレスの解釈を強制的に変更することで、
動的に取得したクラスメソッドにアクセスできるようになる。