Antes que nada tengo que admitir que mis habilidades de programación son bastante limitadas y me hice cargo de un proyecto C++ OOP (realmente pequeño) donde intento introducir mis propios recursos. Desafortunadamente, Estoy experimentando un problema que va más allá de mi conocimiento y espero encontrar algo de ayuda aquí. Estoy trabajando con una biblioteca de terceros (que no se puede cambiar) para tomar imágenes de una cámara y usaré algunos nombres de marcadores de posición aquí.Puntero de función para problemas de función de miembro de clase
La biblioteca de terceros tiene una función "ThirdPartyGrab" para iniciar una captura continua en vivo y toma un puntero a una función que se invocará cada vez que llegue un nuevo marco. Así que en una aplicación normal C dice así:
ThirdPartyGrab (HookFunction);
"HookFunction" tiene que ser declarado como:
long _stdcall HookFunction (long, long, void*);
o "BUF_HOOK_FUNCTION_PTR", que se declara como
typedef long (_stdcall *HOOK_FUNCTION_PTR) (long, long, void*);
Ahora Tengo una aplicación C++ y una clase "MyFrameGrabber" que debe encapsular todo lo que hago. Así que puse en la función de enlace como un miembro privado como esto:
long _stdcall HookFunction (long, long, void*);
También hay una función pública vacío "StartGrab" en mi clase que debe comenzar el Grab. Dentro Trato de llamar:
ThirdPartyGrab (..., HookFunction, ...);
cuales (como es lógico) falla. Dice que la llamada de función a MyFrameGrabber :: HookFunction pierde la lista de argumentos y debería intentar usar & MyFrameGrabber :: HookFunction para crear un puntero en su lugar. Sin embargo, al pasar "& MyFrameGrabber :: HookFunction" se produce otro error que no se puede convertir a BUF_HOOK_FUNCTION_PTR.
Después de leer el C++ FAQ function pointers creo que entiendo el problema pero no puedo encontrar una solución. Intenté que la función de enlace fuera estática, pero esto también da como resultado un error de conversión. También pensé en poner la función de gancho fuera de la clase, pero necesito usar funciones de clase dentro de la función de gancho. ¿Hay alguna otra manera o necesito cambiar todo mi concepto?
EDITAR 14.01.08: Probé la solución única porque no puedo cambiar la biblioteca de terceros y el puntero vacío es solo para los datos que se usan dentro de la función de enlace. Por desgracia, no funcionó de la caja como yo esperaba .... No sé si la función estática tiene que estar en una clase separada así que lo puse en mi clase "MyFrameGrabber":
static MyFrameGrabber& instance()
{
static MyFrameGrabber _instance;
return _instance;
}
long Hook(long, long, void*); // Implementation is in a separate cpp file
en mi cpp que tienen la función call_hook:
long MFTYPE call_hook(long x, MIL_ID y, void MPTYPE *z)
{
return MyFrameGrabber::instance().Hook(x,y,z);
}
void
MyFrameGrabber::grab()
{
ThirdPartyGrab(..., call_hook, ...);
}
Pero esto me da un error en static MatroxFrameGrabber _instance;
que se encontró ningún constructor estándar a juego. Eso es correcto porque mi MyFrameGrabber constructor se ve así:
MyFrameGrabber (void* x,
const std::string &y, int z,
std::string &zz);
traté de poner en un constructor vacío MyFrameGrabber();
pero esto resulta en un error de vinculador. ¿Debo pasar los parámetros vacíos al constructor MyFrameGrabber en el singleton? ¿O necesito tener una clase de enganche separada y, en caso afirmativo, cómo puedo acceder a las funciones de MyFrameGrabber? Gracias por adelantado.
SEGUNDA EDICIÓN 15.01.08: Apliqué los cambios y compila y enlaces ahora. Desafortunadamente, todavía no puedo probar esto en tiempo de ejecución porque es una DLL y aún no tengo Debug Caller Exe y hay otros problemas durante la inicialización, etc. Marcaré la publicación como respuesta porque estoy seguro de que esta es la manera correcta de hacerlo.
Creo que con "biblioteca de terceros" el PO quiere decir que no puede cambiar la biblioteca. Sin embargo, mi suposición puede estar equivocada. – gimpf
@gimpf - gracias, que probablemente tengan razón ... –
Un uso común del vacío * parámetro en C devoluciones de llamada es como el puntero this-> para C++. Eso significa que escribirás mucho (Hook, Hook) y omitirás la static hook_instance – MSalters