C Syntax :: Function passed as parameter,函数从哪里获取参数?

C Syntax :: Function passed as parameter, where does function get its arguments?

我正在阅读网络数据包检测程序 nDPI 的 C 代码。 (available here) 大多数原始代码我都可以理解,但这一行让我很吃惊(针对本论坛略有删节):

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

Embedding 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_loop”的引用的代码文件,但从未看到 pcap_loop() 函数。原谅我,但是根据我找到的代码,您确定项目的其他地方一定有一个 pcap_loop() 吗?我可以假设 pcap_loop() 函数必须存在,并且它必须在某个链接的 .c 文件或其他文件中吗?谢谢!

@Barmar -- 谢谢,我将开始阅读回调函数。非常有用的指针。 :)

And here’s what flummoxes me: “ndpi_process_packet()” requires three arguments. But as far as I can tell, the “if()” line doesn’t provide any. So how are those arguments being submitted to “ndpi_process_packet()”? Where might I look to see where those arguments are coming from?

您需要查看 pcap_loop 如何使用这些参数。据我所知, pcap_loop 未在该项目中定义。它是外部库 libpcap 的一部分。

所以如果你搜索 libpcap,你会发现 this function:

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

接下来,找到that function定义的地方:

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

回调是这样调用的:

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

这些是传递给 ndpi_process_packet() 的参数。