c++ - parametros - punteros en c
degradar la función boost:: a un puntero de función simple (5)
¿Puedes hacerlo funcionar con bind?
cb_t cb = *g.target<cb_t>(); //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<bind_t>();
Tenga en cuenta que esto podría funcionar o no. No tengo forma de probarlo.
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<void (Variable*, void*)> triggerProc ...
InitVariable(triggerProc);
error C2664: ''InitVariable'' : cannot convert parameter 1 from
''boost::function<Signature>'' 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<R,F,L>'' 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 devolución de llamada al estilo C se almacena como un único puntero que apunta a un código ejecutable. Cualquier boost :: function <no trivial va a necesitar al menos dos punteros: uno para el código ejecutable, el otro para los datos que se necesitan para configurar la llamada (por ejemplo, el puntero ''this'', en el caso de un miembro vinculado) función).
La forma correcta de usar boost :: function y boost :: bind con C callbacks es crear una función shim que satisfaga la firma de devolución de llamada, 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<void(int)> pfn = static_cast<boost::function<void(int)> >(userData);
pfn(x);
}
boost::function<void(int)> fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);
Por supuesto, si su firma de devolución de llamada no incluye algún tipo de puntero de datos de usuario, no tiene suerte. Pero cualquier devolución de llamada 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.
¿Puedes hacerlo funcionar con bind?
#include <boost/function.hpp>
#include <boost/bind.hpp>
void f(int x)
{
(void) x;
_asm int 3;
}
typedef void (*cb_t)(int);
int main()
{
boost::function<void (int x)> g = boost::bind(f, 3);
cb_t cb = *g.target<cb_t>(); //target returns null
cb(1);
return 0;
}
actualización: Bien, bien, la intención es vincular un método en una función de devolución de llamada. ¿y ahora que?
Creo que quieres usar la función de miembro target () de boost :: function (no es un bocado ...)
#include <boost/function.hpp>
#include <iostream>
int f(int x)
{
return x + x;
}
typedef int (*pointer_to_func)(int);
int
main()
{
boost::function<int(int x)> g(f);
if(*g.target<pointer_to_func>() == f) {
std::cout << "g contains f" << std::endl;
} else {
std::cout << "g does not contain f" << std::endl;
}
return 0;
}
vea la página de correo de boost [boost] [Function] Problema usando target () con boost :: mem_fn y boost :: bind