2012-03-30 14 views
24

Sono intrappolato in una situazione di discussione passando in libev.Libev, Come passare argomenti ai callback rilevanti

Di solito, libev riceve i pacchetti in una funzione come * * receive_callback, va bene, ma in pratica, abbiamo bisogno di inviare un parente * * write_callback a che fare con lavori specifici in base al pacchetto ricevuto. Per esempio:

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: 
     // ....... 
} 

la mia domanda è, se la write_callbackX deve anche leggere il contenuto specifico nel recv_buff, come possiamo passare l'argomento recv_buff al callbackX? Dobbiamo sopportare il peso e la bruttezza delle variabili globali qui?

+18

Questa è la risposta corretta, se vuoi puoi scriverla come una vera risposta e accettarla, rende più facile per le altre persone trovare le informazioni. – dnaq

+3

Almeno sei tornato indietro e hai continuato a fare ricerche piuttosto che aspettare una risposta :) Sono contento che l'hai risolto. –

+15

Suggerisco di scrivere la soluzione come risposta (e quindi accettarla) invece di modificarla nella domanda – Shahbaz

risposta

5

L'autore ha risposto lui stesso, ma in un commento. Dal momento che questo si presenta come senza risposta, io sono pubblicando la sua risposta nella sezione "risposta" e chiudendo il ciclo. Non sono sicuro se c'è un modo migliore ... sentiti libero di sistemarlo.

Domanda autore dice:

dispiace, penso che ho avuto la risposta ora, e si sentono profonda vergogna al mio disattenzione della documentazione di lettura:

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); 

E poi usiamo il my_io come questo:

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

se sto usando la memoria heap in somedata, qual è l'approccio corretto per liberarlo? –

+0

Non capisco. Come si può ev_io * w_ essere castato in (struct my_io *) nel callback my_cb? – lppier

+0

@lppier 'ev_io' è il primo membro in' my_io' quindi il suo indirizzo può essere ottenuto da quel cast. –

1

Sì, è spiegato nel documento libev, e c'è un altro modo. Ogni osservatore ha un membro dati void * che si può leggere o modificare, e libev sarà completamente ignorare, in modo da poter passare l'argomento come questo:

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; 
    ... 
} 

vedere libev document.

+0

utilizzando -> data è un modo molto più piacevole di farlo rispetto alla tecnica di "sottoclasse" – matiu

Problemi correlati