|
Структура указателей. |
|
|
|
May 3 2015, 07:23
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
У меня каждая команда принимаемая из терминала привязана к своей функции. Функции бывают разные - возвращающие значение, не возвращающие значение, с одним аргументом, двумя аргументами и так далее. Я решил собрать все мои функции в структуру и потом присваивать соответствующий указатель. Код typedef struct { void (*fp1)(void); void (*fp2)(uint32_t); void (*fp3)(uint32_t, uint32_t); void (*fp4)(uint32_t, uint32_t, uint32_t); uint32_t (*fp5)(uint32_t); uint32_t (*fp6)(uint32_t, uint32_t); uint32_t (*fp7)(uint32_t, uint32_t, uint32_t); //uint32_t (*fp5)(double x, double p[], double c); } fp;
struct command { char *name; //command name uint32_t minargs; uint32_t maxargs; uint32_t minval; uint32_t maxval; //uint32_t return_type; //void *varp; //return pointer to variable fp read_func_pointer; fp write_func_pointer; };
struct command commands[] = { {"gsm", 1, 2, 0, 0, ???? , ???? }, {"ifb", 0, 1, 0, 0, ????, ???? }, }; Не могу никак сообразить как мне подставить указатель в команду (там где вопросительные знаки).
|
|
|
|
|
 |
Ответов
|
May 3 2015, 17:23
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Jenya7 @ May 3 2015, 10:23)  У меня каждая команда принимаемая из терминала привязана к своей функции... Как уже отвечал в предыдущей теме, в вашей задаче проще парсить входящий буфер в массив указателей на подстроки. Тогда arg[0] будет командой, а все остальные arg - ее параметры Т.е. в результате должно получиться как-то так: Код struct cmd { char* name; void* (*proc)(void*); };
void* cmd1_proc(char** arg) { while(NULL != *arg++){ .. } }
scruct cmd cmds[]={ { .cmd="cmd1", .proc=cmd1_proc }, .. }
.. if(strcmp(arg[0], cmds[i].name)) cmds[i].proc(&arg[1]);
|
|
|
|
|
May 4 2015, 05:31
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(psL @ May 3 2015, 22:23)  Как уже отвечал в предыдущей теме, в вашей задаче проще парсить входящий буфер в массив указателей на подстроки. Тогда arg[0] будет командой, а все остальные arg - ее параметры Т.е. в результате должно получиться как-то так: Код struct cmd { char* name; void* (*proc)(void*); };
void* cmd1_proc(char** arg) { while(NULL != *arg++){ .. } }
scruct cmd cmds[]={ { .cmd="cmd1", .proc=cmd1_proc }, .. }
.. if(strcmp(arg[0], cmds[i].name)) cmds[i].proc(&arg[1]); то есть Код void* (*proc)(void*); это генерик указатель? Я могу подставить любую функцию? при подстановке получаю: Error[Pe144]: a value of type "uint32_t (*)(uint32_t, uint32_t)" cannot be used to initialize an entity of type "void *(*)(void *)"
Сообщение отредактировал Jenya7 - May 4 2015, 05:39
|
|
|
|
|
May 4 2015, 19:12
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Jenya7 @ May 4 2015, 08:31)  то есть Код void* (*proc)(void*); это генерик указатель? Я могу подставить любую функцию? Нет. Эта функция в таком виде в данном конкретном случае не нужна. Нужно вот так, с некоторыми оговорками: Код //char cmd[] = "test";// arg1 arg2"; //char test[] = "test arg1 arg2"; char test[] = "test2";
struct cmd { char* name; int (*cmd)(char** args); };
int cmd_test(char** args) { enum { ARG1=1, ARG2=2 }; int argc=ARG1;
printf("CMD test,");
if(!args) { printf("required parameters!\n"); return -1; }
do { switch(argc++) { case ARG1: printf(" ARG1: %s", *args); break;
case ARG2: printf(" ARG2: %s", *args); break;
default: printf("Unknown param: %s\n", *args); break; }
} while(*++args);
printf("\n");
return 0; }
int cmd_test2(char** args) { printf("CMD test2\n");
return 0; }
struct cmd cmds[] = { { .name = "test", .cmd = cmd_test }, { .name = "test2", .cmd = cmd_test2 }, };
int main () { int argc, i;
argc = parse_command(test, args);
for(i=0;i<sizeof(cmds)/sizeof(struct cmd); i++) { if(!strcmp(cmds[i].name, args[0])) cmds[i].cmd(args[1]?&args[1]:NULL); }
return 0; } Для расширения функциональности нужно просто дописывать функцию и добавлять ее в таблицу команд cmds[] Пример разбора аргументов - в cmd_test, test2 - как пример второй команды. В случае управляющего терминала видимо команда должна сразу выдавать результат работы в выходной буфер последовательного порта, поэтому вот так.
|
|
|
|
Сообщений в этой теме
Jenya7 Структура указателей. May 3 2015, 07:23 AHTOXA Цитата(psL @ May 3 2015, 22:23) в вашей з... May 3 2015, 19:01   Jenya7 Цитата(psL @ May 5 2015, 00:12) Для расши... May 5 2015, 05:15    psL Цитата(Jenya7 @ May 5 2015, 08:15) спасиб... May 5 2015, 06:21 desh Можно сделать так
CODE
#include <stdint.h>
... May 4 2015, 09:59 Jenya7 Цитата(desh @ May 4 2015, 14:59) Можно сд... May 4 2015, 10:30 desh Посмотрите в stdarg.h. Он не укусит May 4 2015, 10:37 Jenya7 Цитата(desh @ May 4 2015, 15:37) Посмотри... May 4 2015, 11:08  desh Цитата(Jenya7 @ May 4 2015, 14:08) даже н... May 4 2015, 12:49   Jenya7 Цитата(desh @ May 4 2015, 17:49) что то т... May 4 2015, 13:03 desh ну тогда для особых любителей третьей команды можн... May 4 2015, 13:10 Jenya7 Цитата(desh @ May 4 2015, 18:10) ну тогда... May 4 2015, 13:31
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|