- 源码解读
- 备注:函数指针
源码解读
// SPDX-License-Identifier: GPL-2.0 #include备注:函数指针#include #include #include "subcommands.h" #include "version.h" const char *PROG_NAME; static const struct { const char *subcommand; int (*function)(int, const char**); const char *description; } subcommands[] = { { "show", show_main, "Shows the current configuration and device information" }, { "showconf", showconf_main, "Shows the current configuration of a given WireGuard interface, for use with `setconf'" }, { "set", set_main, "Change the current configuration, add peers, remove peers, or change peers" }, { "setconf", setconf_main, "Applies a configuration file to a WireGuard interface" }, { "addconf", setconf_main, "Appends a configuration file to a WireGuard interface" }, { "syncconf", setconf_main, "Synchronizes a configuration file to a WireGuard interface" }, { "genkey", genkey_main, "Generates a new private key and writes it to stdout" }, { "genpsk", genkey_main, "Generates a new preshared key and writes it to stdout" }, { "pubkey", pubkey_main, "Reads a private key from stdin and writes a public key to stdout" } }; static void show_usage(FILE *file) { fprintf(file, "Usage: %s []nn", PROG_NAME); fprintf(file, "Available subcommands:n"); for (size_t i = 0; i < sizeof(subcommands) / sizeof(subcommands[0]); ++i) fprintf(file, " %s: %sn", subcommands[i].subcommand, subcommands[i].description); fprintf(file, "You may pass `--help' to any of these subcommands to view usage.n"); } int main(int argc, const char *argv[]) { PROG_NAME = argv[0]; if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "version"))) { printf("wireguard-tools v%s - https://git.zx2c4.com/wireguard-tools/n", WIREGUARD_TOOLS_VERSION); return 0; } if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) { show_usage(stdout); return 0; } if (argc == 1) { static const char *new_argv[] = { "show", NULL }; return show_main(1, new_argv); } for (size_t i = 0; i < sizeof(subcommands) / sizeof(subcommands[0]); ++i) { if (!strcmp(argv[1], subcommands[i].subcommand)) return subcommands[i].function(argc - 1, argv + 1); } fprintf(stderr, "Invalid subcommand: `%s'n", argv[1]); show_usage(stderr); return 1; }
关于函数指针的用法,本人认为是C语言的经典精华部分,在各大高性能软件中,都会看到类似的用法,尤其是在Nginx的源码中,更是用到极处。
比如在nginx源码中:typedef size_t (*ngx_log_handler_pt) (void *ctx, char *buf, size_t len);
举个最直接简单的例子吧,
#includeusing namespace std; typedef int (*Pointer) (char, char); int ss(char a, char b) { cout<<"in func ss()"< cout<<"in func bb()"< Pointer p; p = ss; p('a','b'); p = bb; p('a', 'b'); return 0; }
通过p来调用两个函数。
运行结果:
in func ss() a b in func bb() b a
当然了,这种函数指针,跟静态数组以及偏移量结合起来使用,不但能简洁源代码,并且能大大提升程序的运行效率。



