views:

1604

answers:

8

Hi,

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.

Here is what I did from my constructor:

m_cRedundencyManager->Init(this->RedundencyManagerCallBack);

This doesn't compile - I get the following error:

Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member

I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.

Any suggestions/explanation for this??

I'm using VS2008.

Thanks!!

ofer

+2  A: 

What argument does Init take? What is the new error message?

Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?

Konrad Rudolph
A: 

I can see that the init has the following override:

Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)

where CALLBACK_FUNC_EX is typedef void (*CALLBACK_FUNC_EX)(int, void *);

ofer
+1  A: 

Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.

Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.


// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);

// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);

// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
    ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
e.James
+1  A: 

A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.

If your API expects a nonmember callback function, that's what you have to pass to it.

jalf
A: 

This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think.

Onorio Catenacci
+9  A: 

As you now showed your init function accepts a non-member function. so do it like this:

static void Callback(int other_arg, void * this_pointer) {
    CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
    self->RedundencyManagerCallBack(other_arg);
}

and call Init with

m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);

That works because a function pointer to a static member function is not a member function pointer and can thus be handled like just a pointer to a free function.

Johannes Schaub - litb
A: 

here is a nice article abt function pointer

yesraaj
+6  A: 
Joseph Garvin