2012-03-30 9 views
24

Ich bin in einer Situation des Arguments in Libev übergeben.Libew, Wie Argumente an relevante Rückrufe übergeben

Normalerweise erhält libev Pakete in einer Funktion wie * receive_callback *, das ist in Ordnung, aber in der Praxis brauchen wir ein relativ * versenden write_callback * mit bestimmten Projekten gemäß dem empfangenen Paket zu behandeln. Zum Beispiel:

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

Meine Frage ist, ob die write_callbackX auch den spezifischen Inhalt in der recv_buff zu lesen hat, wie können wir das recv_buff Argument an die callbackX passieren? Müssen wir hier die Last und Hässlichkeit globaler Variablen tragen?

+18

Das ist die richtige Antwort, wenn Sie möchten, können Sie es als eine echte Antwort schreiben und akzeptieren, macht es einfacher für andere Menschen, die Informationen zu finden. – dnaq

+3

Wenigstens bist du zurückgegangen und hast weiter geforscht, anstatt auf eine Antwort zu warten :) Schön, dass du es gelöst hast. –

+15

Ich schlage vor, Ihre Lösung als Antwort zu schreiben (und dann zu akzeptieren), anstatt sie in der Frage – Shahbaz

Antwort

5

Der Autor antwortete es selbst, aber in einem Kommentar. Da dies als unbeantwortet angezeigt wird, bin ich posten seine Antwort in der "Antwort" -Sektion und schließen Sie die Schleife. Nicht sicher, ob es einen besseren Weg gibt ... zögern Sie nicht, dies zu beheben.

Frage Autor sagt:

Sorry, ich glaube, ich jetzt die Antwort bekam, und fühlen sich tief beschämt an meinem Sorglosigkeit Lesen der Dokumentation:

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

Und dann verwenden wir die my_io wie dies:

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

zu bearbeiten, wenn ich Heap-Speicher in Somedata verwende, was ist der richtige Ansatz, um es zu befreien? –

+0

Ich verstehe es nicht. Wie kann ev_io * w_ im my_cb Callback in (struct my_io *) umgewandelt werden? – lppier

+0

@lppier Das 'ev_io' ist das erste Mitglied in' my_io', so dass seine Adresse durch diese Besetzung erhalten werden kann. –

1

Ja, es ist erklärt in Libev Dokument, und es gibt einen anderen Weg. Jeder Beobachter hat einen void * Datenelement, das Sie lesen oder ändern können, und libev wird es völlig ignorieren, so können Sie das Argument wie folgt passieren:

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

siehe libev document.

+0

mit -> Daten ist ein besserer Weg, es als die 'Unterklasse' Technik zu tun – matiu