2012-03-30 10 views
24

Jestem uwięziony w sytuacji kłótni przechodzącej w libev.Libev, Jak przekazywać argumenty do odpowiednich wywołań zwrotnych

Zazwyczaj libev odbiera pakiety w zależności jak * receive_callback *, to jest OK, ale w praktyce, musimy wysyłką względną * write_callback * do czynienia z konkretnych zadań zgodnie z odebranym pakiecie. Na przykład:

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

Moje pytanie brzmi, czy write_callbackX ma również do zapoznania się z konkretną zawartość w recv_buff, w jaki sposób możemy przekazać argument recv_buff do callbackX? Czy musimy tutaj ponosić ciężar i brzydotę globalnych zmiennych?

+18

To jest poprawna odpowiedź, jeśli chcesz, możesz zapisać ją jako prawdziwą odpowiedź i zaakceptować ją, ułatwia innym osobom znalezienie informacji. – dnaq

+3

Przynajmniej wróciłeś i prowadziłeś badania, zamiast czekać na odpowiedź :) Cieszę się, że to rozwiązałeś. –

+15

Proponuję napisać twoje rozwiązanie jako odpowiedź (a następnie zaakceptować) zamiast edytować je w pytaniu – Shahbaz

Odpowiedz

5

Autor odpowiedział na to sam, ale w komentarzu. Ponieważ to pokazuje się jako bez odpowiedzi, jestem umieszczanie odpowiedzi w sekcji "odpowiedź" i zamknięcie pętli. Nie wiem, czy jest lepszy sposób ... możesz to naprawić.

Pytanie autor mówi:

Niestety, myślę, że dostałem odpowiedź teraz, i czuję się głęboko zawstydzony na moim nieuwagi dokumentacji Reading:

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

A potem używamy my_io jak to:

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

, jeśli używam pamięci sterty w somedata, jakie jest prawidłowe podejście do jej uwolnienia? –

+0

Nie rozumiem tego. W jaki sposób ev_io * w_ może zostać wrzucone do (struct my_io *) w wywołaniu zwrotnym my_cb? – lppier

+0

@lppier 'ev_io' jest pierwszym członkiem' my_io', więc jego adres można uzyskać za pomocą tej obsady. –

1

Tak to wyjaśnione w dokumencie libev, i jest inny sposób. Każdy obserwator ma człon danych void *, które można odczytać lub modyfikowania i libev będzie całkowicie zignorować, więc można przekazać argument takiego:

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

widzieć libev document.

+0

użycie -> danych to lepszy sposób na zrobienie tego niż technika "podklasy" – matiu

Powiązane problemy