Либев передать аргумент для обратного вызова - PullRequest
1 голос
/ 02 мая 2020

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

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

1 Ответ

0 голосов
/ 02 мая 2020

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

ОБЪЕДИНЕНИЕ ТАМОЖЕННЫХ ДАННЫХ С НАБЛЮДАТЕЛЕМ

Каждый наблюдатель имеет по умолчанию элемент 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.

...