Cast pointer to member function to normal pointer
The difference between a C function and a C++ member function is that C function uses cdecl calling convention, while member functions uses thiscall calling convention (and you can't even take their address!).
As I understand, you actually want that secondFunc()
to call the member function of a particular instance of class (let's call it this
). Well, addresses of member functions of all the instances of a particular class are the same. In order to pass the pointer to the object, you will need a side channel. In this case it could be static variable. Or, if you want MT support, you'll have to use Thread Local Storage (TLS),
This requires one callback per SomeFunc
-type member, but you would need a dispatcher somewhere anyway.
C++ class member function pointer to function pointer
No. A member function is not a free function. The type is entirely different, and a pointer to a member function (PTMF) is a completely different, incompatible object from a function pointer. (A PTMF is usually much bigger, for example.) Most importantly a pointer-to-member must always be used together with an instance pointer to the object whose member you want to call, so you cannot even use a PTMF the same way you use a function pointer.
The easiest solution for interacting with C code is to write a global wrapper function that dispatches your call, or to make your member function static (in which case it becomes essentially a free function):
// global!
Engine * myEngine;
int theCallback(lua_State * L)
{
return myEngine->pcall_log(L);
}
Engine::Run()
{
/* ... */
myEngine = this;
luabind::set_pcall_callback(&theCallback);
/* ... */
}
The conceptual problem here is that you have an engine class, although you will practically only have one single instance of it. For a genuine class with many objects, a PTMF wouldn't make sense because you'd have to specify which object to use for the call, whereas your engine class perhaps is essentially a singleton class which could be entirely static (i.e. a glorified namespace).
cast a pointer to member function in derived class to a pointer to abstract member function
You could shorten this example a lot:
struct B {
virtual void foo() = 0;
};
struct D : B {
void foo() override { }
};
int main() {
void (B::*ptr)() = &D::foo; // error: cannot initialize a variable of
// type 'void (B::*)()' with an rvalue of type
// 'void (D::*)()': different classes ('B' vs 'D')
}
The error message, at least on clang, is pretty clear. gcc just says cannot initialize. The issue is just that you cannot implicitly convert a pointer-to-derived-member to a pointer-to-base-member. But you can do it explicitly with static_cast
:
void (B::*ptr)() =
static_cast<void (B::*)()>(&D::foo); // ok!
Side-note: please remove the CALL_MBR_FUNC
macro from your code and never write such a thing ever again.
Cast pointer to member function to intptr_t
No, the spec does not allow you to cast function pointers or member pointers to intptr_t. The reason for this is because you may need more than one intptr_t's worth of data to describe them. For example, member pointers on gcc are 3 intptr_t's long, and MSCVs range from 1 to 4 intptr_t's long. Much of this is used to handle virtual functions.
On some old hardware (that C++ supports), pointers are also actually smaller than function pointers. This happens on small systems where you may only need to point to an 8-bit memory structure, but programs get loaded into a 16-bit program memory space.
Much of the time, this pattern you are trying to use is used to create delegates: member function pointers permanently tied to a specific object. This can be done with 2 int pointers and a wrapping function
struct Delegate
{
intptr_t obj; // I'll use intptr_t here, but often this is void*
intptr_t func;
};
// you need one of these for each type of mfp you use
static void callT_Test(intptr_t obj)
{
T* realObj = reinterpret_cast<T*>(obj);
realObj->test();
}
// constructing a delegate to call test on t
Delegate d;
d.obj = reinterpret_cast<intptr_t>(&t);
d.func = &callT_Test;
Related Topics
Forward Declare a Standard Container
How to Hash and Compare a Pointer-To-Member-Function
Should I Return Exit_Success or 0 from Main()
Why Can't I Capture This By-Reference ('&This') in Lambda
Difference Between <String> and <String.H>
Why Does Printf("%F",0); Give Undefined Behavior
How to Check If a Type Is an Instantiation of a Given Class Template
What Is the Precision of Long Double in C++
In C++ , What's So Special About "_Move_H"
How to Identify Platform/Compiler from Preprocessor MACros
How Does the Custom Deleter of Std::Unique_Ptr Work