libev передает аргумент для обратного вызова

Когда мы вызываем ev_io_init, мы даем ему адрес функции, которая имеет (struct ev_loop*, struct ev_io, int) параметры, но как мы можем сделать параметры, подобные (struct ev_loop*, struct ev_io, int, void *ptr), и заставить ev_io_init вызывать ее с постоянным значением ptr?

Я знаю, как переносить дополнительные данные из struct ev_io*, но сохранять одни и те же данные для каждого события - не лучший способ, я думаю


person dvjawgvdhawgvbda    schedule 01.05.2020    source источник


Ответы (1)


Из документации:

СВЯЗЬ ПОЛЬЗОВАТЕЛЬСКИХ ДАННЫХ С СМОТРОМ

У каждого наблюдателя по умолчанию есть void *data член, который вы можете прочитать или изменить в любое время: libev полностью его проигнорирует. Это можно использовать для связывания произвольных данных с вашим наблюдателем. Если вам нужно больше данных, и вы не хотите выделять память отдельно и хранить указатель на нее в этом элементе данных, вы также можете «подклассифицировать» тип наблюдателя и предоставить свои собственные данные:

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

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

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

Более интересные и менее совместимые с C способы преобразования типа вашей функции обратного вызова были опущены.

Поскольку вы просто хотите передать один указатель, самый простой способ - это просто вставить его в поле data.

person Joseph Sible-Reinstate Monica    schedule 02.05.2020