C Синтаксис :: Функция, переданная как параметр, откуда функция получает свои аргументы? - PullRequest
0 голосов
/ 13 июля 2020

Я читаю код C для nDPI, программы проверки сетевых пакетов. ( доступен ей e) Большая часть исходного кода, который я могу проследить, но эта строка бросила меня (немного сокращено для этого форума):

if(pcap_loop(1, 2, &ndpi_process_packet, 3) < 0)
      printf("Error while reading pcap file!\n");

Таким образом, оператор if() обернут вокруг звонка на pcap_loop. Это та ссылка на «&ndpi_process_packet», которая меня интересует. Оказывается, «ndpi_process_packet()» - это функция, определенная в другом месте кода:

static void ndpi_process_packet(u_char *args,
                                const struct pcap_pkthdr *header,
                                const u_char *packet) {
   ...blah blah blah...
}

Встраивание операторов printf() заставляет меня думать, что первая строка вызывает pcap_loop и передает адрес «ndpi_process_packet()» в качестве параметра. Я понимаю общую концепцию передачи функции в качестве параметра, но здесь меня это смущает.

И вот что меня смущает: «ndpi_process_packet()» требует трех аргументов. Но, насколько я могу судить, строка «if()» ничего не дает. Так как же эти аргументы передаются в «ndpi_process_packet()»? Где я могу посмотреть, откуда берутся эти аргументы?

В случае, если это актуально (я не думаю, что это так), я добавлю, что pcap_loop - это не функция, а переход кусок кода в другой функции:

pcap_loop:
  runPcapLoop(thread_id);
  if(playlist_fp[thread_id] != NULL) { /* playlist: read next file */
    char filename[256];
    if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) == 0 &&
       (ndpi_thread_info[thread_id].workflow->pcap_handle = pcap_open_offline(filename, pcap_error_buffer)) != NULL) {
      configurePcapHandle(ndpi_thread_info[thread_id].workflow->pcap_handle);
      goto pcap_loop;
    }

Есть мысли по этому поводу? Спасибо.

РЕДАКТИРОВАНИЕ ДЛЯ КОММЕНТАРИЙ ... @KamilCuk - Спасибо, ваше наблюдение действительно полезно. Я просмотрел файлы кода на предмет всех ссылок на «pcap_l oop» и никогда не видел функцию pcap_l oop (). Простите меня, но, судя по размещенному мною коду, вы уверены, что где-нибудь в проекте должен быть pcap_l oop ()? Могу ли я предположить, что функция pcap_l oop () должна существовать, и она должна быть в каком-то связанном файле. c или что-то в этом роде? Спасибо!

@ Barmar - Спасибо, я начну читать о функциях обратного вызова. Очень полезный указатель. :)

1 Ответ

1 голос
/ 13 июля 2020

И вот что меня смущает: «ndpi_process_packet()» требует трех аргументов. Но, насколько я могу судить, строка «if()» ничего не дает. Так как же эти аргументы передаются в «ndpi_process_packet()»? Откуда я могу посмотреть, откуда берутся эти аргументы?

Вам нужно посмотреть, как pcap_l oop использует эти аргументы. Насколько я могу судить, pcap_l oop не определен в этом проекте. Это часть внешней библиотеки libpcap.

Итак, если вы выполните поиск в libpcap, вы найдете эту функцию :

int
pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Она сохраняет указатель функции на переменная называется callback. Итак, нам нужно выяснить, как он использует callback.

Затем посмотрите на эту строку:

n = pcap_offline_read(p, cnt, callback, user);

Итак, он вызывает другую функцию и передает ей callback.

Затем найдите, где определена эта функция :

int
pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Обратный вызов вызывается так:

(*callback)(user, &h, data);

И это аргументы, которые передан на ndpi_process_packet().

...