How to Pass a Member Function to a Function Pointer

How can I pass a member function where a free function is expected?

There isn't anything wrong with using function pointers. However, pointers to non-static member functions are not like normal function pointers: member functions need to be called on an object which is passed as an implicit argument to the function. The signature of your member function above is, thus

void (aClass::*)(int, int)

rather than the type you try to use

void (*)(int, int)

One approach could consist in making the member function static in which case it doesn't require any object to be called on and you can use it with the type void (*)(int, int).

If you need to access any non-static member of your class and you need to stick with function pointers, e.g., because the function is part of a C interface, your best option is to always pass a void* to your function taking function pointers and call your member through a forwarding function which obtains an object from the void* and then calls the member function.

In a proper C++ interface you might want to have a look at having your function take templated argument for function objects to use arbitrary class types. If using a templated interface is undesirable you should use something like std::function<void(int, int)>: you can create a suitably callable function object for these, e.g., using std::bind().

The type-safe approaches using a template argument for the class type or a suitable std::function<...> are preferable than using a void* interface as they remove the potential for errors due to a cast to the wrong type.

To clarify how to use a function pointer to call a member function, here is an example:

// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}

void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}

struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};

void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}

int main() {
somefunction(&non_member, nullptr);
foo object;
somefunction(&forwarder, &object);
}

How Can I Pass a Member Function to a Function Pointer?

You can't. You either pass a pointer to a static method or Parent has to accept also a pointer to the object.

You might want to look at boost::bind and boost::function for that:

#include <boost/bind.hpp>
#include <boost/function.hpp>
struct Y
{
void say(void) { std::cout << "hallo!";}

boost::function<void()> getFunc() { return boost::bind(&Y::say, this); }
};

struct X
{
//non-boost:
void (Y::*func)();
Y* objectY;
void callFunc() { (objectY->*func)(); }

//boost version:
boost::function<void()> f;

};

X x;
Y y;
x.f = boost::bind(&Y::say, boost::ref(y));
x.f = y.getFunc();
x.f();
x.func = &Y::say;
x.objectY = &y;
x.callFunc();

Assign C++ member function to C function pointer

You simply cannot do this. Member functions have an implicit this argument that is a pointer to the object on which the function is being called. A function that does not take a B* as an argument will never manage to run on a specific B instance and a function that does not take this point as its first argument can never have the same signature as a class method. For more details on this problem and an example of a workaround read:

https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr

Pay attention to the note at the bottom of the answer on how static member functions can be used in such manner.

Pure C++ projects can use std::function & std::bind to achieve what you are asking about, but a C library used by a C++ project cannot work with these types.

Calling C++ member functions via a function pointer

Read this for detail :

// 1 define a function pointer and initialize to NULL

int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;

// C++

class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };

/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore

// Calling Function using Function Pointer

(*this.*pt2ConstMember)(12, 'a', 'b');

How to pass a pointer to a member function to a C function?

Kindly refer to detailed topic about

How to Implement a Callback to a static C++ Member Function ?

How to Implement a Callback to a non-static C++ Member Function ?

http://www.newty.de/fpt/callback.html

How do I pass a member function to a function that expects a function pointer?

The problem here is that a member function expects a "hidden" first argument that is a this pointer. Loosely speaking, a member function

void Func(int a, double b);

is equivalent to a free function

void Func(MyClass* this, int a, double b);

There is no way to pass a this pointer via ClassicFuncPtr, and std::function tricks won't help you here. target() doesn't do any magic, it just returns a pointer to the stored function if types match, and in your code they don't, that's why you get a null pointer. std::bind returns a functional object (that stores this inside), but a functional object is quite distinct from a function pointer and can't be converted into one.

Given that you can't change the callback type, there is a pretty ugly and fragile work-around that uses a static variable to store the value of this pointer. It should give you the idea of how to make it work, at least in principle.

class MyClass {
public:
void Test() {
thisPtr = this;
CallMyFunc(MemberFuncInvoker);
}

private:
inline static MyClass* thisPtr;

static void MemberFuncInvoker(int a, double b) {
thisPtr->MemberFunc(a, b);
}

void MemberFunc(int a, double b) {
std::cout << "a = " << a << ", b = " << b << '\n';
}
};

Note that static member functions don't expect a hidden this argument and behave like free functions in this respect (due to the absence of this argument, you can't access non-static data members inside a static member function).

Demo


Typically, callbacks are accompanied with a void*-like parameter that can be used to pass a this pointer. For example, theEnumWindows function from WinAPI has the signature

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

That lParam is passed to a callback

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);

Then, inside a free (or static) callback function you could do:

reinterpret_cast<MyClass*>(lParam)->MyMemberFunction(hwnd);


Related Topics



Leave a reply



Submit