Necesito convertir algunos punteros a funciones miembro para void*
punteros (porque necesito para empujarlos a la Lua apilar, pero el problema no es Lua relacionado).Llamar a un ++ puntero de función miembro de C: este puntero se corrompe
Lo hago usando un union
. Pero cuando convierto los punteros de función de miembro a void*
y viceversa y luego intento llamar al puntero con una instancia de la clase, el puntero this
se daña. Extrañamente, este problema no ocurre, si convierto el puntero void*
en un puntero a función C con un puntero a la clase como su primer parámetro.
Aquí es una pieza de código que muestra el problema:
#include <iostream>
using namespace std;
class test
{
int a;
public:
void tellSomething()
{
cout << "this: " << this << endl;
cout << "referencing member variable..." << endl;
cout << a << endl;
}
};
int main()
{
union
{
void *ptr;
void (test::*func)();
} conv1, conv2;
union
{
void *ptr;
void (*func) (test*);
} conv3;
test &t = *new test();
cout << "created instance: " << (void*) &t << endl;
// assign the member function pointer to the first union
conv1.func = &test::tellSomething;
// copy the void* pointers
conv2.ptr = conv3.ptr = conv1.ptr;
// call without conversion
void (test::*func1)() = conv1.func;
(t.*func1)(); // --> works
// call with C style function pointer invocation
void (*func3) (test*) = conv3.func;
(*func3) (&t); // --> works (although obviously the wrong type of pointer)
// call with C++ style member function pointer invocation
void (test::*func2)() = conv2.func;
(t.*func2)(); // `this' is the wrong pointer; program will crash in the member function
return 0;
}
Esa es la salida:
created instance: 0x1ff6010
this: 0x1ff6010
referencing member variable...
0
this: 0x1ff6010
referencing member variable...
0
this: 0x10200600f
referencing member variable...
zsh: segmentation fault (core dumped) ./a.out
Es esto un error en el compilador (GCC)? Sé que esta conversión entre void*
y punteros de función (miembro) no es compatible con el estándar, pero lo curioso es que funciona al convertir el void*
en un puntero de función de estilo C.
¿Has comprobado el tamaño de() de tu memfunptr? En mi implementación es mayor que sizeof (void *) – PlasmaHH