degradar la función boost :: a un puntero de función simple

quiere pasar boost :: bind a un método que espera un puntero de función simple (misma firma).

typedef void TriggerProc_type(Variable*,void*); void InitVariable(TriggerProc_type *proc); boost::function triggerProc ... InitVariable(triggerProc); error C2664: 'InitVariable' : cannot convert parameter 1 from 'boost::function' to 'void (__cdecl *)(type *,void *)' 

Puedo evitar almacenar una función boost :: y pasar el functor enlazado directamente, pero luego aparece un error similar:

 error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter 1 from 'boost::_bi::bind_t' to 'void (__cdecl *)(type *,void *)' 

    ¿Alguien ha notado que la respuesta aceptada solo funciona con casos triviales? La única forma en que la función <> :: target () devolverá un objeto que puede vincularse a una devolución de llamada C, es si se construyó con un objeto que puede vincularse con una devolución de llamada C. Si ese es el caso, entonces podrías haberlo enlazado directamente y haber omitido todas las funciones <> absurdas para empezar.

    Si lo piensas, no hay ninguna solución mágica para esto. Una callback al estilo C se almacena como un único puntero que apunta a un código ejecutable. Cualquier boost :: function

    La forma correcta de usar boost :: function y boost :: bind con C callbacks es crear una función shim que satisfaga la firma de callback, averigüe a qué función <> llamar y la llama. Por lo general, las devoluciones de llamadas C tendrán algún tipo de vacío * para ‘datos de usuario’; ahí es donde escondes tu puntero de función:

     typedef void (*CallbackType)(int x, void* user_data); void RegisterCallback(CallbackType cb, void* user_data); void MyCallback(int x, void* userData) { boost::function pfn = static_cast >(userData); pfn(x); } boost::function fn = boost::bind(myFunction(5)); RegisterCallback(MyCallback, &fn); 

    Por supuesto, si su firma de callback no incluye algún tipo de puntero de datos de usuario, no tiene suerte. Pero cualquier callback que no incluya un puntero de datos de usuario ya no se puede utilizar en la mayoría de los escenarios del mundo real y debe volverse a escribir.

    Creo que quieres usar la función de miembro target () de boost :: function (no es un bocado …)

     #include  #include  int f(int x) { return x + x; } typedef int (*pointer_to_func)(int); int main() { boost::function g(f); if(*g.target() == f) { std::cout < < "g contains f" << std::endl; } else { std::cout << "g does not contain f" << std::endl; } return 0; } 

    ¿Puedes hacerlo funcionar con bind?

     cb_t cb = *g.target(); //target returns null 

    Esto es por diseño . Básicamente, dado que bind devuelve un tipo completamente diferente, no hay forma de que esto funcione. Básicamente, un objeto proxy de enlace no se puede convertir a un puntero de función C (ya que no es uno: es un objeto de función). El tipo devuelto por boost::bind es complicado. El estándar actual de C ++ no permite una buena forma de hacer lo que desea. C ++ 0x estará equipado con una expresión de tipo decltype que podría usarse aquí para lograr algo como esto:

     typedef decltype(bind(f, 3)) bind_t; bind_t target = *g.target(); 

    Tenga en cuenta que esto podría funcionar o no. No tengo forma de probarlo.

    vea la página de correo de boost [boost] [Function] Problema usando target () con boost :: mem_fn y boost :: bind

    ¿Puedes hacerlo funcionar con bind?

     #include  #include  void f(int x) { (void) x; _asm int 3; } typedef void (*cb_t)(int); int main() { boost::function g = boost::bind(f, 3); cb_t cb = *g.target(); //target returns null cb(1); return 0; } 

    actualización: Bien, bien, la intención es vincular un método en una función de callback. ¿y ahora que?