2

does C\C++ Support a mechanism for callback function ? and how to create it ? I've written several code, to create callback function in C++ but it failed ..

    #include<iostream>
    using namespace std;

    void callee()
    {
         printf("callee\n"); 
         printf("calleeeeeeeeee\n"); 
    }

    void callback(void* func)
    {
         printf("callback\n");     
    }

    int main()
    {
        void (*call)(void*);
        void (*call2)(void);
        call2 = &callee;
        call = &callback;
        call((void*)call2);    
        getchar();
        return 0;    
    }
Ken White
  • 123,280
  • 14
  • 225
  • 444
Yoshua Joo Bin
  • 517
  • 3
  • 6
  • 15
  • Note: This isn't C code. What is your error message? – autistic Feb 24 '13 at 07:19
  • `call((void*)call2);` is most likely your error cause...simply because a function pointer cannot be cast to a void *. Each function parameter needs to match the function prototype. So no, generic callbacks are not supported if I'm not mistaken. – Refugnic Eternium Feb 24 '13 at 07:21
  • There was no error but it only gave me "callback" as an output, the "callee" function didn't executed :( – Yoshua Joo Bin Feb 24 '13 at 07:22
  • For the general part of the question, see here: http://stackoverflow.com/questions/2298242/callback-functions-in-c – jogojapan Feb 24 '13 at 07:23
  • This SO question may help you on your way. http://stackoverflow.com/questions/2485219/generic-callbacks – Refugnic Eternium Feb 24 '13 at 07:25
  • have a look at http://stackoverflow.com/questions/6183847/callback-functions-in-c-c-c http://stackoverflow.com/questions/2298242/callback-functions-in-c http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/Callback-Functions-Tutorial.htm, these link should help you understand basic concept behind callback and their usage... – Saqlain Feb 24 '13 at 07:27
  • Um... `iostream` and `namespace std` are not `c`. Please use tags that actually apply to your question. – Ken White Feb 24 '13 at 07:29

3 Answers3

10

I don't know C++, I wrote up some C code, hope it helps

#include <stdio.h>

void call( int, void ( *f )( int ) );
void called( int );

int main( int argc, char const *argv[] ){
    printf( "start\n" );
    call( 1, called );
    printf( "end\n" );
    getchar();
    return 0;
}

void call( int a, void ( *f )( int ) ){
    printf( "doing stuff\n" );
    printf( "a: %d\n", a );
    printf( "going to call back\n" );
    f( a * 2 );
}

void called( int b ){
    printf( "b: %d\n", b );
    printf( "b*2: %d\n", b*2 );
    printf( "call back function being called\n" );
}

Calling call back functions in a function is no more than having a function pointer and call the function whenever you finished your planed job.

I modified the code and made it up to be more clear to show how you would use call backs.
This is the result you will see, if you compile and run it:

start
doing stuff
a: 1
going to call back
b: 2
b*2: 4
call back function being called
end

Well, either the author edited the question or someone edited it for him, there's no longer the C tag. Ignore this answer if you don't want to see pure C code. I'm just gonna leave it here in case anyone could be interested.

pochen
  • 873
  • 12
  • 22
2

Well, you never called "callee" - you executed "callback" with "call(void*)call2);", but in order for your "callee" function to execute, you need to run it from within your "callback" function. Here, this works:

#include <iostream>
#include <stdio.h>
using namespace std;

void callee()
{
     printf("callee\n");
     printf("calleeeeeeeeee\n");
}

void callback(void* func)
{
    void (*mCallbackFunc)(void);

    printf("callback\n");

    mCallbackFunc = (void(*)())func;
    mCallbackFunc();
}

int main()
{
    void (*call)(void*);
    void (*call2)(void);
    call2 = &callee;
    call = &callback;

    call((void*)call2);

    return 0;
}

Output:

callback
callee
calleeeeeeeeee
enhzflep
  • 12,927
  • 2
  • 32
  • 51
  • hmm ouh i have to execute the function that is passed into parameter, right ? – Yoshua Joo Bin Feb 24 '13 at 07:46
  • Bingo! That's exactly it. Operations with function pointers are often easier to read if you typedef the function pointer first, but it's just a matter of looking pretty. As you point out - you need to explicitly do something with the passed in parameter - in this case, execute the function it points to. – enhzflep Feb 24 '13 at 08:00
0

Here is an example of using callbacks with interfaces.

//listener observer design pattern
class MonitoringElements{
public:

//information to monitor

};

class ICondition{
public:
    virtual ~ICondition(){}

    virtual bool didTrigger(const MonitoringElements& current) = 0;
    virtual void risingEdge() = 0;
};

class MonitorManager final{
public:


    void addCondition(ICondition* condition){
        m_conditions.push_back(condition);
    }

    //constantly monitoring every x seconds
    void monitorOnce(){
        update();
        for(int i = 0; i < m_conditions.size(); ++i)
            if(m_conditions.at(i)->didTrigger(m_monitorElements)){
                m_conditions.at(i)->risingEdge();
            }
    }

private:
    void update(){
        //read sensor values here
        //update m_monitorElements;
    }

    MonitoringElements m_monitorElements;
    std::vector<ICondition*> m_conditions;
};
Babak
  • 1