Есть ли лучший способ ... чем оператор switch?
Составьте список всех допустимых кодов действий (константа в памяти программы, чтобы она не использовала мало вашей оперативной памяти) и последовательно сравнивайте каждый из них с полученным кодом. Возможно, зарезервировать индекс «0» для обозначения «неизвестный код действия».
Например:
// Warning: untested code.
typedef int (*ActionFunctionPointer)( int, int, char * );
struct parse_item{
const char action_letter;
const int action_number; // you might be able to get away with a single byte here, if none of your actions are above 255.
// alas, http://reprap.org/wiki/G-code mentions a "M501" code.
const ActionFunctionPointer action_function_pointer;
};
int m0_handler( int speed, int extrude_rate, char * message ){ // M0: Stop
speed_x = 0; speed_y = 0; speed_z = 0; speed_e = 0;
}
int g4_handler ( int dwell_time, int extrude_rate, char * message ){ // G4: Dwell
delay(dwell_time);
}
const struct parse_item parse_table[] = {
{ '\0', 0, unrecognized_action } // special error-handler
{ 'M', 0, m0_handler }, // M0: Stop
// ...
{ 'G', 4, g4_handler }, // G4: Dwell
{ '\0', 0, unrecognized_action } // special error-handler
}
ActionFunctionPointer get_action_function_pointer( char * buffer ){
char letter = get_letter( buffer );
int action_number = get_number( buffer );
int index = 0;
ActionFunctionPointer f = 0;
do{
index++;
if( (letter == parse_table[index].action_letter ) and
(action_number == parse_table[index].action_number) ){
f = parse_table[index].action_function_pointer;
};
if('\0' == parse_table[index].action_letter ){
index = 0;
f = unrecognized_action;
};
}while(0 == f);
return f;
}
Как можно поступить с указателями на функции в C, когда имена (и
возможно подписи) может поменяться? Если функции подписи
иначе, это вообще возможно?
Можно создать указатель на функцию в C, которая (в разное время) указывает на функции с более или менее параметрами (разными сигнатурами), используя varargs.
Кроме того, вы можете принудительно заставить все функции, на которые может указывать указатель этой функции, иметь одинаковые параметры и возвращаемое значение (одну и ту же сигнатуру), добавив «фиктивные» параметры к функциям, для которых требуется меньше остальные.
По моему опыту, подход "фиктивных параметров" легче понять и использовать меньше памяти, чем подход varargs.
Есть ли способ ввести определение общего типа этой подписи
быть переданным и вызванным от?
Да.
В значительной степени все код, который я когда-либо видел, который использует указатели на функции
также создает typedef для ссылки на этот конкретный тип функции.
(За исключением, конечно, запутанных конкурсных работ ).
См. Приведенный выше пример и Wikibooks: программирование на C: подробные указатели на функции .
p.s .:
Есть ли какая-то причина, по которой вы заново изобретаете колесо?
Может быть, может быть, один из следующих уже существующих интерпретаторов G-кода для AVR подойдет вам, возможно, с небольшими изменениями?
проигрывал ,
Sprinter ,
Marlin ,
Прошивка Teacup ,
sjfw ,
Makerbot ,
или же
Grbl ?
(См. http://reprap.org/wiki/Comparison_of_RepRap_Firmwares).