C++ Callback

原创 2011年01月09日 14:13:00

C++ Callback

2006/3/26 15:17:02
 

This fully functional example shows how in C++ callbacks can be done in an absolutely flexible way!

This demo is written in Visual Studio 6 but the Callback class is platform independent and also runs under Linux, Mac, and so forth....

Callbacks in C++ are not as simple as in C. Pure C functions are from the type __cdecl. C++ functions are from the type __thiscall. (They differ in the way how they pass arguments on the stack.)

In C++, you have classes and, additionally, instances of classes. Every instance uses its own memory area for storing class variables. The pointer to this area of variables is the "this" pointer. It represents the instance. Every time you call any C++ function, the "this" pointer is passed to the function as an invisible parameter! (M$ Visual Studio 6 uses the processor register ECX to pass the "this" pointer.)

So, in C++ it is not enough to store the address of the function, which you want to call back. You also have to store the "this" pointer!

Using the Callback Class

You can include "Callback.h" into your project. The usage it is very simple because the cCallback class has only two member functions: SetCallback() and Execute(). You can understand the following examples without knowing what is happening inside cCallback.

cMyProject.h:

#include "callback.h"

private:
    // the functions of your project
    void CallbackFox   (int Param);
    void CallbackRabbit(int Param);
    void TestTheCallback(cCallback *pCallbackFunction, int Param);

    // Some instances of the Callback class
    TCallback<cMyProject> i_Callback_1;
    TCallback<cMyProject> i_Callback_2;

cMyProject.cpp:

void cMyProject::CallbackRabbit(int Param)
{
    char Buf[50];
    sprintf(Buf, "Now I'm in Rabbit with Param %d !/n", Param);
    printf(Buf);
}

void cMyProject::CallbackFox(int Param)
{
    char Buf[50];
    sprintf(Buf, "Now I'm in Fox with Param %d !/n", Param);
    printf(Buf);
}

void TestTheCallback(cCallback *pCallbackFunction, int Param)
{
    pCallbackFunction->Execute(Param * Param);
}

void cMyProject::CallbackDemo()
{
    // defining where the callback should jump to
    i_Callback_1.SetCallback(this, &cMyProject::CallbackRabbit);
    i_Callback_2.SetCallback(this, &cMyProject::CallbackFox);

    // now you can pass i_Callback like a pointer to a function
    TestTheCallback(&i_Callback_1, 4);
    TestTheCallback(&i_Callback_2, 5);
}

If you call cMyProject::CallbackDemo(), the output will be:

Now I'm in Rabbit with Param 16 !
Now I'm in Fox    with Param 25 !

Callback Re-Definitions

It is also possible to re-define the callback with SetCallback() as often as you like:

void cMyProject::CallbackDemo()
{
    i_Callback_1.SetCallback(this, &cMyProject::CallbackRabbit);
    TestTheCallback(&i_Callback_1, 4);

    i_Callback_1.SetCallback(this, &cMyProject::CallbackFox);
    TestTheCallback(&i_Callback_1, 5);
}

The output would be the same, but i_Callback_2 is not needed anymore.

Callback Arrays

It is also possible to use arrays of callbacks:

cMyProject.h:

private:
    TCallback<cMyProject> i_Callback[10];

cMyProject.cpp:

void TestTheCallback(int Index, int Param)
{
    i_Callback[Index].Execute(Param * Param);
}

void cMyProject::CallbackDemo()
{
    i_Callback[0].SetCallback(this, &cMyProject::CallbackRabbit);
    i_Callback[1].SetCallback(this, &cMyProject::CallbackFox);
    i_Callback[2].SetCallback(.....);

    TestTheCallback(0, 4);
    TestTheCallback(1, 5);
}

Callback Arrays, Part 2

In the above example, all callbacks are from cMyProject. In i_Callback you can ONLY store callbacks to the cMyProject class because it is defined as TCallback<cMyProject>.

If you want to store callbacks to different classes in a callback array, you have to create the array from cCallback instead of TCallback:

cMyProject.h:

private:
    cCallback *p_Callback[10];

cMyProject.cpp:

void cMyProject::StoreCallback(cCallback *p_CallbackFunction,
                               int Index)
{
    p_Callback[Index] = p_CallbackFunction;
}

StoreCallback() then can be called by ANY class to set a callback to itself. For example:

cDemo.h:

private:
    TCallback<cDemo> i_MyCallback;

cDemo.cpp:

#include "cMyProject.h"
extern cMyProject i_MyProject;
......
    i_MyCallback.SetCallback(this, &cDemo::MyCallbackFunction);

    i_MyProject.StoreCallback(&i_MyCallback, Index);
......

You can even later modify i_MyCallback with SetCallback() without having to call StoreCallback() again!!

In the source code (see the download link at the end of this article) you find a different example, and additionally a demonstration of a global callback, which you need, if you want to be called back by the operating system. (Windows API callbacks always go into the global namespace.)

The Callback Class

Finally, here comes the great cCallback class itself. It consits of only a header file without a corresponding cpp file.

Callback.h:

class cCallback
{
    public:
        virtual void Execute(int Param) const =0;
};


template <class cInstance>
class TCallback : public cCallback
{
    public:
        TCallback()    // constructor
        {
            pFunction = 0;
        }

        typedef void (cInstance::*tFunction)(int Param);

        virtual void Execute(int Param) const
        {
            if (pFunction) (cInst->*pFunction)(Param);
            else printf("ERROR : the callback function has not
                                 been defined !!!!");
        }

        void SetCallback (cInstance  *cInstancePointer,
                          tFunction   pFunctionPointer)
        {
            cInst     = cInstancePointer;
            pFunction = pFunctionPointer;
        }

    private:
        cInstance  *cInst;
        tFunction  pFunction;
};

This class defines an Execute() function that takes one integer parameter and returns no parameter (void). You can simply adapt it to your needs; for example, a callback that takes five paramaters and returns a bool. (Then, you have to modify three lines: the two lines beginning with "virtual void Execute" and the typedef.)

To completely understand this class, you need advanced C++ knowledge. I will not explain all the details here because this would be too much.

Instead I recommend the very good book:
Author: André Willms
Title: C++ Programming (German title: "C++ Programmierung")
Publisher: Addison Wesley
ISBN 3-8273-1495-X

And from my homepage, you can download free C++ books in the compiled HTML format.

c++回调函数 callback

(1)Callback方式 Callback的本质是设置一个函数指针进去,然后在需要需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型。比如下面的示例代码,我们在Dow...
  • u011135902
  • u011135902
  • 2016年01月23日 23:10
  • 247

Callback在C\C++中的实现

Callback是这样的一类对象(在这里不能简单的理解为"回调函数"了):你注册一个函数,以及调用它时的参数,希望在满足某个条件时,以这些注册的函数调用这个回调,完成指定的操作. 很多地方会使用...
  • weiqubo
  • weiqubo
  • 2013年11月27日 15:45
  • 2463

C++中回调(CallBack)的使用方法

回调函数是一个很有用,也很重要的概念。当发生某种事件时,系统或其他函数将会自动调用你定义的一段函数。回调函数在windows编程使用的场合很多,比如Hook回调函数:MouseProc,GetMsgP...
  • force_eagle
  • force_eagle
  • 2009年07月14日 13:48
  • 24599

C++中回调函数(CALLBACK)初探

C++中回调函数(CALLBACK)初探 简介 对于很多初学者来说,往往觉得回调函数很神秘,很想知道回调函数的工作原理。本文将要解释什么是回调函数、它们有什么好处、为什么要使用它们等等问题,在开始...
  • liubing8609
  • liubing8609
  • 2014年11月23日 14:52
  • 1170

c++callback回调实例

静态库文件: Func.h: #ifndef _Func_H #define _Func_H #endif #include "stdafx.h" #include using name...
  • u011555996
  • u011555996
  • 2017年07月26日 15:12
  • 465

c++实现Callback机制

c++实现Callback机制          Callback是这样的一类对象(在这里不能简单的理解为"回调函数"了):你注册一个函数,以及调用它时的参数,希望在满足某个条件时,以这些注...
  • chenglinhust
  • chenglinhust
  • 2015年01月02日 23:08
  • 1544

C++中回调函数(CallBack)的使用

如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。 其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而...
  • bzhxuexi
  • bzhxuexi
  • 2013年09月17日 12:54
  • 6212

C/C++中Windows API 简单的(Callback)回调机制

C/C++中Windows API 简单的(Callback)回调机制
  • qq78442761
  • qq78442761
  • 2017年07月01日 10:55
  • 2593

浅谈C/C++回调函数(Callback)& 函数指针

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定...
  • u012339743
  • u012339743
  • 2017年04月08日 23:49
  • 1834

c++11 lambda as callback

class tempClass { public: tempClass(); ~tempClass(); template void test(T func) { MessageBo...
  • kingsollyu
  • kingsollyu
  • 2013年08月15日 14:34
  • 1148
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ Callback
举报原因:
原因补充:

(最多只允许输入30个字)