Подтвердить что ты не робот

Либев, Как передать аргументы соответствующим обратным вызовам

Я попал в ситуацию передачи аргументов в libev.

Обычно libev получает пакеты в функции типа * receive_callback *, это нормально, но на практике нам нужно отправить относительный * write_callback *, чтобы иметь дело с конкретными рабочих мест в соответствии с полученным пакетом. Например:

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

Мой вопрос: если write_callbackX также должен прочитать конкретный контент в recv_buff, как мы можем передать аргумент recv_buff в callbackX? Должны ли мы нести бремя и уродство глобальных переменных здесь?

4b9b3361

Ответ 1

Автор ответил сам, но в комментарии. Поскольку это проявляется как безответное, я отправляя ответ в разделе "ответ" и закрывая цикл. Не уверен, есть ли лучший способ... не стесняйтесь исправить это.

Автор вопроса говорит:

Извините, я думаю, что получил ответ сейчас, и мне было очень стыдно за мое небрежность документации для чтения:

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

И затем мы используем my_io следующим образом:

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

Ответ 2

Да, это объясняется в документе libev, и есть другой способ. Каждый наблюдатель имеет элемент данных void *, который вы можете читать или изменять, а libev полностью игнорирует его, поэтому вы можете передать аргумент следующим образом:

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

см. libev document.