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
How to Signify No More Input for String Ss in the Loop While (Cin >> Ss)
How to Set the Decimal Separator to Be a Comma
Force All Classes to Implement/Override a 'Pure Virtual' Method in Multi-Level Inheritance Hierarchy
Specialization of Templated Member Function in Templated Class
Get Pointer to Object from Pointer to Some Member
Boost Async_* Functions and Shared_Ptr'S
Implicit Conversion from Char** to Const Char**
Trouble Launching Cuda Kernels from Static Initialization Code
C++ What Is the Purpose of Casting to Void
What Does a Backslash in C++ Mean
Check If a Pointer Points to Allocated Memory on the Heap
When Including Header Files, Is the Path Case Sensitive
How to Create a Shared Library with Cmake
Acquire/Release Semantics with Non-Temporal Stores on X64