2012-03-30 12 views
24

Estoy atrapado en una situación de discusión pasando en libev.Libev, Cómo pasar argumentos a las devoluciones de llamada relevantes

Por lo general, libev recibe paquetes en una función como * * receive_callback, eso está bien, pero en la práctica, tenemos que enviar a un pariente * * write_callback para hacer frente a los trabajos específicos de acuerdo con el paquete recibido. Por ejemplo:

S_RECV_MSG* pstRecvMsg = (S_RECV_MSG*) recv_buff; 
switch(pstRecvMsg->wMsgType) { 
    case 1: 
     ev_io_init(w, write_callback1, w->fd, EV_WRITE); 
     break; 
    case 2: 
     ev_io_init(w, write_callback2, w->fd, EV_WRITE); 
     break; 
    case 3: 
     // ....... 
} 

Mi pregunta es, si el write_callbackX también tiene que leer el contenido específico en el recv_buff, ¿cómo podemos pasar el argumento recv_buff a la callbackX? ¿Debemos soportar la carga y la fealdad de las variables globales aquí?

+18

Esa es la respuesta correcta, si lo desea puede escribirlo como una respuesta real y aceptarlo, hace que sea más fácil para otras personas encontrar la información. – dnaq

+3

Al menos volviste y seguiste investigando en lugar de esperar por una respuesta :) Me alegro de que lo hayas resuelto. –

+15

Sugiero que escriba su solución como respuesta (y luego la acepte) en lugar de editarla en la pregunta – Shahbaz

Respuesta

5

El autor lo respondió solo, pero en un comentario. Como esto aparece como sin respuesta, estoy publicando su respuesta en la sección "respuesta" y cerrando el ciclo. No estoy seguro si hay una mejor manera ... siéntase libre de arreglar esto.

autor pregunta dice:

Lo siento, creo que tengo la respuesta ahora, y se siente profundamente avergonzado en mi descuido de la documentación de la lectura:

struct my_io{ 
    ev_io io; 
    int otherfd; 
    void *somedata; 
    struct whatever *mostinteresting; 
}; 
// ... 
struct my_io w; 
ev_io_init (&w.io, my_cb, fd, EV_READ); 

Y luego usamos el my_io como esto:

static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) 
{ 
    struct my_io *w = (struct my_io *)w_; 
    //... 
} 
+0

si estoy usando la memoria de pila en algunos datos, ¿cuál es el enfoque correcto para liberarla? –

+0

No lo entiendo ¿Cómo se puede incluir ev_io * w_ en (struct my_io *) en la devolución de llamada my_cb? – lppier

+0

@lppier El 'ev_io' es el primer miembro en' my_io', por lo que su dirección se puede obtener con ese molde. –

1

sí, es explicado en documento de liberación, y hay otra manera. Cada observador tiene un miembro de datos void * que se pueden leer o modificar y libev va a ignorar por completo, por lo que puede pasar el argumento de la siguiente manera:

w->data = (void *)recv_buff; 
... 
static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) 
{ 
    S_RECV_MSG *recv_buff = (S_RECV_MSG*)w_->data; 
    ... 
} 

ver libev document.

+0

usando -> los datos son una manera más fácil de hacerlo que la técnica de 'subclases' – matiu

Cuestiones relacionadas