0%

DPDK example: 命令行参数解析

参数读取

初始化 EAL,并获取剩余参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <errno.h>

#include <rte_eal.h>
#include <rte_common.h>

typedef struct cfgs {
uint32_t num;
char *string;
bool mode;
} cfgs_t;

enum {
CMD_OPT_NUM = 1,
CMD_OPT_STRING,
CMD_OPT_MODE,
};

static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"num", required_argument, NULL, CMD_OPT_NUM},
{"string", required_argument, NULL, CMD_OPT_STRING},
{"mode", no_argument, NULL, CMD_OPT_MODE},

{0,0,0,0}
};

static void print_usage(const char *prgname)
{
printf("%s [OPTIONS]\n", prgname);
printf("--help Help\n");
printf("--num <uint32> Num\n");
printf("--string <string> String\n");
printf("--mode Mode\n");
}

bool str_to_uint32(const char *str, uint32_t *num) {
char *endptr;
errno = 0;
unsigned long val = strtoul(str, &endptr, 10);

if (errno != 0 || *endptr != '\0' || val > UINT32_MAX) {
return false;
}
*num = (uint32_t)val;
return true;
}

static uint32_t parse_num(const char *arg) {
uint32_t value;

if (str_to_uint32(arg, &value))
{
return value;
}
rte_exit(EXIT_FAILURE, "Failed to parse num\n");
}

static cfgs_t parse_args(int argc, char **argv) {
cfgs_t cfgs;
char *prgname = argv[0];

// 设置默认值
cfgs.num = 0;
cfgs.string = NULL;
cfgs.mode = false;

int option_id;
while ((option_id = getopt_long_only(argc, argv, "h", long_options, NULL)) != -1)
{
switch (option_id)
{
case 'h':
print_usage(prgname);
rte_exit(EXIT_SUCCESS, "Exit APP\n");
case CMD_OPT_NUM:
cfgs.num = parse_num(optarg);
break;
case CMD_OPT_STRING:
cfgs.string = optarg;
break;
case CMD_OPT_MODE:
cfgs.mode = true;
break;

default:
print_usage(prgname);
rte_exit(EXIT_FAILURE, "Invalid command line parameter\n");
}
}
return cfgs;
}


int main(int argc, char **argv){
// 初始化EAL
int ret;
ret = rte_eal_init(argc, argv);
if (ret < 0)
{
rte_exit(EXIT_FAILURE, "Failed to init eal");
}

// 去除掉被EAL使用了的参数
argc -= ret;
argv += ret;

// 解析其他参数
cfgs_t cfgs = parse_args(argc, argv);
printf("num: %d\n", cfgs.num);
printf("string: %s\n", cfgs.string);
printf("mode: %d\n", cfgs.mode);

printf("Finished initiation\n");
}

运行

1
2
3
4
5
6
7
8
9
10
root@ubuntu2404:/home/guoyi/dpdk-stable-24.11.1/build# ./examples/dpdk-playground -- --num 1 --string "abd" --mode
EAL: Detected CPU lcores: 3
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
num: 1
string: abd
mode: 1
Finished initiation