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;    
    }
7
  • Note: This isn't C code. What is your error message? Commented Feb 24, 2013 at 7: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. Commented Feb 24, 2013 at 7:21
  • There was no error but it only gave me "callback" as an output, the "callee" function didn't executed :( Commented Feb 24, 2013 at 7:22
  • For the general part of the question, see here: stackoverflow.com/questions/2298242/callback-functions-in-c Commented Feb 24, 2013 at 7:23
  • This SO question may help you on your way. stackoverflow.com/questions/2485219/generic-callbacks Commented Feb 24, 2013 at 7:25

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice :), i got that :) Thank you :)
@prM, +1. What do you mean by "whenever you finished your planed job"? Thanks!
@user1847726 err, just a function call (to the given function pointer) statement at the very end of the function body.
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

2 Comments

hmm ouh i have to execute the function that is passed into parameter, right ?
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.
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;
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.