Содержимое переменной как указатель на функцию.

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Здравствуйте форумчане!

Искал искал, вроде бы нашел. На деле оказалось мало понятно как можно применить то что я задумал из того материала что я успел нагуглить. Вполне возможно что я вовсе не то ищу. Прошу вашей подсказки)

Есть мысль о неком устройстве, которое принимает разного рода команды. Мол, а сколько времени, а померяй-ка температуру, перезагрузись, расскажи о чем думаешь в данный момент и так далее.

Начал я писать такой код (опустим сбор данных из uart)

execBuffer = uartBuffer;

if (execBuffer == "getTemerature") getTemperature();
if (execBuffer == "getVarMassives") getVarMassives();
if (execBuffer == "reboot") reboot();

void getTemperature(){
// measure
}

void getVarMassives(){
//get some vars and send
}

void reboot(){
//rebooting requence
}

И тут меня начал душить перфекционист, мол какого "трехногого осьминога" я пишу

if (execBuffer == "getTemerature") getTemperature();

если в содержимом переменной уже содержится имя функции необходимой к выполнению.

По сути нужно сказать программе \ компилятору "дружок, вот в этой переменной есть имя функции которую нужно запустить"

Надеюсь что вас тоже смутило, это значит что вы меня понимаете.

Если количество функций выдет в 10 это будет как пом мне кака-код

Я пытался понять как именно можно вызвать функцию из переменной. Стало известно чть есть некие указатели * и ссылки $ но применить их примерно так

*execBuffer;

Это было бы идеально, но оно не работает.

Я бы использовал скажем switch()

Но мое жесткое делание использовать человекоимена там не свойственны. Там только цифры. Как быть, как жить товарщи? Есть варианты? Куда хоть копать?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ПС: а подумать?

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Благодарю за очень объемный ответ который приблизил меня к решению задачи ровно на 0,00 %
И все же. Мои попытки я исчерпал. Сюда обращаюсь в том самом крайном случае и стараюсь не завешивать форум вопросами мол "я новичок, памагити". Знаете, подскажите, не знаете - мимо проходите.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
Pyotr
Offline
Зарегистрирован: 12.03.2014

UserDead пишет:

Я пытался понять как именно можно вызвать функцию из переменной. Стало известно чть есть некие указатели * и ссылки $ но применить их примерно так

*execBuffer;

Это было бы идеально, но оно не работает.

Я бы использовал скажем switch()

Но мое жесткое делание использовать человекоимена там не свойственны. Там только цифры. Как быть, как жить товарщи? Есть варианты? Куда хоть копать?

Как я понял Вам нужен массив указателей на функции
Пример скетча

#define TOT_FUNC 5
byte n = 0;
void (*printSerial[TOT_FUNC])(void) = {//массив указателей на функции
  printStroka_0,
  printStroka_1,
  printStroka_2,
  printStroka_3,
  printStroka_4
  };

void setup(){
  Serial.begin(9600);
}

void loop(){
  printSerial[n]();
  n = (++n) % 5;
  delay(500);       
}
//==================
void printStroka_0(void){
  Serial.println("stroka_0");
}
//==================
void printStroka_1(){
  Serial.println("stroka_1");
}
//==================
void printStroka_2(){
  Serial.println("stroka_2");
}
//==================
void printStroka_3(){
  Serial.println("stroka_3");
}
//==================
void printStroka_4(){
  Serial.println("stroka_4");
}

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Петр, сдается мне что своим примером Вы привели ТС-а в состояние "за" полной жопой из №1. :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Функции в С по именам не вызываются, нигде не хранится информация об имени функции.  У функции можно только взять адрес и вызвать ее по адресу.  Решение напрашивается такое:  для всех имен функций (в текстовом виде) заранее вычислить хэш или контрольную сумму по простейшему алгоритму, чтобы каждой строке соответствовал свой хэш, вариантов масса, надо пошерстить гуголь по ключевым словам "хэш строки".  Потом создать 2 постоянных массива, один с хэшами всех названий функций, второй с соответствующими им адресами.  При поступлении строки - вычислять её хэш, и искать в первом массиве.  Если нашол такой хэш, брать адрес функции, который лежит по тому же индексу в другом массиве и вызывать её.  Я счас не за компом, с планшета код писать неудобно. Если нада примерчег, то только пожже.  Но я думаю,  лагаритм понятен.  

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Я в сишном коде видел типа такого может оно имеет какой-то смысл (ссаными тряпками не кидать):
 

Temperatura:

temp () {}

Davlenie:

dd() {}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

этта шо?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это "метки" для goto, который хоть и запрещен, но все же существует. :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

синтакически верно только так 

Temperatura:

temp (); {}

Davlenie:

dd(); {}

иначе не компилируеца.  Вот только какова польза отэтова? 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

синтакически верно только так 

Temperatura:

temp (); {}

Davlenie:

dd(); {}

иначе не компилируеца.  Вот только какова польза отэтова? 

откуда я знаю, в васике это указатель на адрес перехода, а вот зачем это в СИ сейчас и узнаем, я жеж говорю, увидел...и даже подивился )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

goto, который хоть и запрещен

Интересное кино. Можно поподробнее, когда, кем, номер и дата документа? 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

ЕвгенийП пишет:

Arhat109-2 пишет:

goto, который хоть и запрещен

Интересное кино. Можно поподробнее, когда, кем, номер и дата документа? 

в 90ые у нас преподаватели любили это повторять, по мне так нормальная команда, вполне себе удобная.

b707
Offline
Зарегистрирован: 26.05.2017

andycat пишет:

в 90ые у нас преподаватели любили это повторять, по мне так нормальная команда, вполне себе удобная.

поскольку все мои знания о Си и о программировании вообще именно оттуда - из 80-90х, то я вырос с тем, что использования goto - признак программиста неудачника :) За все годы ни в одной моей программе ни одного goto не затесалось - даже в самых первых - и ни разу как-то и не было нужды.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

как хорошо что я не программист :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

andycat пишет:
как хорошо что я не программист :)

Вы напоминаете чукчу из анекдота:

Однажды чукча купил «Волгу» и поехал в свое стойбище хвастаться, а как тормозить — забыл. Покружился, покружился, да и врезался с размаху в камень. Машину — вдребезги, сам — в больницу попал. Вернулся через некоторое время из больницы домой и говорит:
— Врачи сказали — хорошо, что мозгов нет, а то было бы сотрясение.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

UserDead,

информация об именах функция во время выполнения недоступна (если не пользоваться всякими чуждыми языку приблудами для загаживания памяти, типа отладочных баз или RTTI).

То, что Вы пытаетесь сделать, я бы делал более системно и об этом кстати, уже не раз вопрос поднимался, но более широко, чем у Вас.

Вопрос ставился так: хочется иметь возможность выполнить произвольную  программу на удалённом контроллере так, чтобы не мешать его работе - не перепрошивать, не перезагружать и т.п.

Идея была использовать какой-нибудь простой, допускающий компактную реализацию интерпретатора язык (пока остановились на диалекте языка Форт). Интерпретатор должен сидеть в контроллере (вместе с его основной прошивкой) и по мере поступления команд, интерпретировать их.

При таком походе можно строить любые диагностические сценарии. Например, вывести HIGH на такой-то пин и посмотреть, что появилость на другом пине и т.п.

В этом языке должна быть возможность выполнять все штатные функции среды и заодно функции основной прошивки.

В принципе это делается не так уж сложно. Главное, чтобы хватало памяти "ещё и на интерпретатор", но до железа этот проект пока не доводился.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Допустим имеем функцию вида

bool testFunc(uint8_t d1, uint16_t* d2){
    //...
    return true;
}

Для того что бы красиво работать с указателем на нее опишем нужный нам тип

typedef bool (*clbc_t)(uint8_t, uint16_t *); 

Теперь мы имеем нужный тип данных (указатель на требуемую нам функцию, и можем им оперировать)

clbc_t myFunc=testFunc;

uint8_t temp1=8;
uint16_t temp2=16;

bool test=myFunc(temp1,&temp2);

Может что написал не по русски, ногами не пинать.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

qwone пишет:

andycat пишет:
как хорошо что я не программист :)

Вы напоминаете чукчу из анекдота:

Однажды чукча купил «Волгу» и поехал в свое стойбище хвастаться, а как тормозить — забыл. Покружился, покружился, да и врезался с размаху в камень. Машину — вдребезги, сам — в больницу попал. Вернулся через некоторое время из больницы домой и говорит:
— Врачи сказали — хорошо, что мозгов нет, а то было бы сотрясение.

 

хм...не понял.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

andycat пишет:
хм...не понял.

Объсняю на пальцах: 

1.Форум называется Ардуино. Здесь собираются те кому интересна Ардуино.

2 Раздел называется Программирование . Здесь собираются те кому интересен такой аспект, как программирование. И чем сложнее проект, тем глубже надо изучать программирование. 

3.

andycat пишет:
как хорошо что я не программист :)

Так что ответ выходит только такой https://www.youtube.com/watch?v=twbYHR7cB5g

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:
goto - признак программиста неудачника :)

Значит, Кнут, Брукс мл., а также разработчики ядра линукса - неудачники. А главные "удачники" - это Вирт с Дейстрой и Хоаром :)))

b707 пишет:
ни разу как-то и не было нужды.

Потому что Ваши предподаватели (считающие goto разновидностью терроризма, педофилии, курения и потребления необезжиренного молока) вдолбили в Вас что а) это неприлично и б) научили Вас хитрым, черезжопным приёмам разруливания простейших ситуаций, лишь бы обойтись без треклятого goto, и эти черезжопные приёмы стали для Вас естсвенными - Вы их используете даже не задумываясь, что порой один goto сократил бы Вам пяток флагов и десяток дополнительных проверок.

Собственно "вред goto" - религиозная догма, умело вбитая в головы поколениям.

 

nik182
Онлайн
Зарегистрирован: 04.05.2015

Тем более, что в машинных кодах AVR только хардкор, только GOTO в виде jmp и branch.   

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Может быть не будем отвлекаться от темы топика :)

умеет qwone программировать без goto через ж.... - да ради бога.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Шибко плюсую!!!
А всё таки вопрос повис в воздухе, умеет компилятор по именам на метку передавать управление?
По идее не должен, одно как-бы данные, второе адреса, и процессор с архитектурой РИСК, так не далеко и до вирусов на микроконтроллерах...

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Собственно "вред goto" - религиозная догма, умело вбитая в головы поколениям.

позвольте с вами не согласится :) видимо я так называемый "структураст" и этого уже не изменить :)

а насчет того, что через goto все быстрее и проще -

"Для любой задачи существует простой и очевидный путь к решению. Но чаще всего этот путь неверный"

но это и правда оффтопик.

 

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

Шибко плюсую!!!
А всё таки вопрос повис в воздухе, умеет компилятор по именам на метку передавать управление?

по именам нет, по ссылка - запросто. Так что можно написать процедурку. которая по имени будет находить в массиве адрес... - получится почти то, что хочет ТС.

Правда это, имхо, совершенно избыточный изврат.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

ЕвгенийП пишет:

b707 пишет:
goto - признак программиста неудачника :)

Значит, Кнут, Брукс мл., а также разработчики ядра линукса - неудачники. А главные "удачники" - это Вирт с Дейстрой и Хоаром :)))

b707 пишет:
ни разу как-то и не было нужды.

Потому что Ваши предподаватели (считающие goto разновидностью терроризма, педофилии, курения и потребления необезжиренного молока) вдолбили в Вас что а) это неприлично и б) научили Вас хитрым, черезжопным приёмам разруливания простейших ситуаций, лишь бы обойтись без треклятого goto, и эти черезжопные приёмы стали для Вас естсвенными - Вы их используете даже не задумываясь, что порой один goto сократил бы Вам пяток флагов и десяток дополнительных проверок.

Собственно "вред goto" - религиозная догма, умело вбитая в головы поколениям.

 

Ха! Порадовали. С каких это пор Вы поете дифирамбы так любимому мною "пшел на"? Не ожидал-с, спасибо. :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:
С каких это пор Вы поете дифирамбы

Всегда писал на этом форуме, что "всякий инструмент хорош, когда используется умело и по назначению", а также, "если из чемоданчика мастера выложить часть инструментов, его работа лучше не станет". 

Я реально это здесь писал много раз. Помните, или ссылки нужны?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Не, не помню и ссылки не требуются ибо не интересно ни разу.

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Немнонго по теме, немного не потеме. Но уже немного яснее.

Выражаю благодарность тем кто отписался и разъяснил про адреса / метки

То что написал brokly не понял. Ну как не понял. Я увидел функцию вложенную в функцию с передачей параметров - не то.

По примеру сказанному DetSimen была мысль такая: Каждая буква - это цифры в ASCII. Каким-то образом сконвертировать представиление из текста в набор цифр и использовать для каждой команды набор цифр в switch(ASCII) но есть то символы двух и трех значные даже если первые незаглавные символы от начала алфавита из двух цифр делать костыль на 3 буквы 97 98 99 a, b и c соответственно - найдичайший костыль. А остальное делить по три цифры чтобы разбить и сконвертировать строку... Уж не знаю какой нужно болеть болезнью чтобы реализовать такое. Но мозг ищет варианты...

То что написано вами ЕвгенийП, выглядит довольно объемно. Это прям станция с возможностью отладки на ходу. Чуть ли не движок. ( Осталось нейросеть для самокоррекции написать  :D ) Мне бы давно следовало сказать что нужно экномить память и не засорять String-ами char-ами память, а использовать кодовые команды. С другой стороны я за понятность команд как со строны общения на уровне клиент-сервер-приложение, так и со стороны коммандования. Вот прям заводит мысль о том что в любой момент можно подкинуться шнурком к контроллеру и поспрашивать его понятными мне командами. Именно теми которыми я в него зашил. К примеру как на маршрутизаторах консольки (show running-config, config > interface ethernet 2 > enable, show version и так далее)

Может не парится и просто тупо выписать как я описал?

if (execBuffer == "getTemperature") getTemperature();

Правда тогда запиханная, простите "в задницу" функция №20, будет дольше всех вызываться пока контроллер по всем if-ам не побегает. Кака-кодинг?!

 

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Получается чтобы реализовать задуманное. Нужно вычислить адрес каждой функции и создать таблицу связи (уже вижу двумерный массив) где адрес сопоставляется с именем функции. Мне достаточно будет просто обратиться к нужной ячейке и дать команду перейти на такой-то адрес хранящийся в двумерном массиве. А правда что при каждой перекомпиляции (или при перезагрузке) адреса меняются. Тогда получается понадобится инициализация в виде вычисления адресов функций каждый раз. Уже похоже на что-то серьезное.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

UserDead, вот я и говорю,то что написал первым. Для вас это полная жопа=комплекс мероприятий. Но если бы нормально знали язык и трюки в нем, то все это счастье можно отправить компилятору, который со всем этим справляется.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015
// функция хэширования строки
//--------------------------------------------------------------------------------------------------------------------------------
#define A_PRIME 54059 /* a prime */
#define B_PRIME 76963 /* another prime */
#define C_PRIME 86969 /* yet another prime */
//--------------------------------------------------------------------------------------------------------------------------------
unsigned int hash_str(const char* s)
{
   unsigned int h = 31 /* also prime */;
   while (*s) {
     h = (h * A_PRIME) ^ (s[0] * B_PRIME);
     s++;
   }
   return h; // or return h % C;
}
//--------------------------------------------------------------------------------------------------------------------------------

Не благодари. Прогони все свои строки с именами функций через хэширование, и создай таблицу, как советовали выше. Входящее значение прогоняешь через хэш, и смотришь в таблице.

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Теперь мне более понятно.

Не гуру в программировании, учусь пока не на книжках, а на опыте. Нахожу себе задачу, и думаю как решить избивая пальцы на клавиатуре в гугле, просматривая форумы и примеры.

Если найду, радуюсь и потом копипастом время от времени использую в других работах пока не выучу способ. А уж потом оптимизация, доработки.

Думаю настанет момент, когда хотелки станут не простыми, и на форуме в меня будут бросаться книжками))

sadman41
Offline
Зарегистрирован: 19.10.2016

Теперь посидите и подумайте: как поступите, если в функции нужно будет параметры передавать. Да и как свой код через полгода читать станете со всеми этими хэшами, няш-мяшами и прочей курагой.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Теперь посидите и подумайте: как поступите, если в функции нужно будет параметры передавать.

Лехко: общий стек, функция сама выгребает параметры извне. Как пример: есть парсер входящих команд, помимо имени функции - выгребает все параметры, хранит их в списке внутри себя. Тогда внутри функции мона делать что-то типа:

CommandParser parser; // наш парсер

void function()
{
 if(parser.argsCount() < 2)
  return;
 
  const char* param1 = parser.getStringParam(0);
  int param2 = parser.getIntParam(1);
}

Так, сходу решение, что называется.

sadman41
Offline
Зарегистрирован: 19.10.2016

Я предложил подумать человеку, который только вчера про указатели узнал.

Да и есть у меня сомнения, что в данном случае наворачивание парсеров перевесит по удобству-экономии десяток-другой ифов.

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Все просто. Если функция внутренняя то она принимает параметры. Если внешняя обычно она является коммандой а присущий параметр будет сидеть в глобальной переменной.

А вот читать для меня не проблема. Я обожаю комментировать код косле того как пришлось "набыдлокодить" в своем первом масштабном проекте. Это три модуля для одной цели в одном устройстве где не менее 600 строк в каждом.
Как-то раз девайс сломался через пол года, и если бы не комментарии я бы рвал волосы сами знаете где в попытках вспомнить как это работает.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

главное детям мороженое, а бабе цветы . И не перепутай кутузов.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Да и есть у меня сомнения, что в данном случае наворачивание парсеров перевесит по удобству-экономии десяток-другой ифов.

Ну это смотря какой проект ;) Скажем, когда несколько сотен команд - имхо лучше парсер, чем несколько сотен ифов.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

UserDead пишет:

Это три модуля для одной цели в одном устройстве где не менее 600 строк в каждом.

Три модуля всего лишь по 600 строк? Это зародыш проекта :), у вас всё ещё впереди. У меня в проектах частенько по несколько десятков тысяч строк кода - ничего, живём.

sadman41
Offline
Зарегистрирован: 19.10.2016

В том-то и дело, что сейчас у нас тут посреди вакуума стоит сферический конь. Думаю, что к тому времени, когда дело дойдет до сотни команд - подход неоднократно поменяется. Поэтому заранее предлагаю ТС оценить масштабируемость и контролируемость его идеи. 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

В том-то и дело, что сейчас у нас тут посреди вакуума стоит сферический конь. 

Не, ну куда без этого то? Обижаете, рожать коней посреди ледянящих межзвёздных просторов - это местный старинный обычай, не будем его нарушать :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну да . Сначала пишется некий "движок", некий "процессор" в котором указатели на функции есть его данные , или даже сказать управляемые "ноги", для вызова различных действий. Да что далеко ходить .Ядро выполнения всех даже не Си-шных языков реализовано на языке ... Си.

Logik
Offline
Зарегистрирован: 05.08.2014

Тема - пример того как небольшая ошибка в начале проекта заводит в дебри а затем и тупик. Вот расскажите, UserDead, с чего Вы решили передавать команды строковыми переменными? Вам так удобней? Очень сомниваюсь. Разве что Вы их с клавиатуры вводите. Да и то проще можна.

Делайте так. Заводим h - файлик, имя protocol.h выглядит для него весьма уместным, в него пишем чтото типа

#include CMD_getTemerature 0

#include  CMD_getVarMassives 1

и т.д Можете для продвинутости enum использовать.

Этот файл присутствует во всех проектах которые передают и принимают команды. Надо передать  - ну пишите Send(CMD_getTemerature). По наглядности это ничем не хуже Send("getTemerature"). Даже лучше, притом компактей компилируется и быстрей работает. А функции при этом реализуются вобще легко и естественно. Пример массива указателей на функции с инициализацией есть в #4. Берете его, а индекс массива уже есть, это те самые CMD_ххххх. Получается принимаем команду cmd=Rcv(); и вызываем соответствующую функцию printSerial[cmd]();. Все просто и мульен раз пройдено, не страдайте фигней.

Иногда бывают ситуации когда действительно надо именно по строковым командам вызывать действия. Например при работе с модемом. Тогда это разумно описывать дето так.

typedef void (*pFn)(char* p);

typedef struct sEventsMap
{
  const char* Name;
  pFn Event;
};

sEventsMap EventsMap[]={
  {"OK",       ReciveOK},
  {"RING",     ReciveRING},

  
 
  {0,0}  //признак конца списка
};

Подробней тут http://arduino.ru/forum/apparatnye-voprosy/gsm-modem-a6-v-rezhime-tcp Но это если нет выхода, команды строковые.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Logik пишет:
Тема - пример того как небольшая ошибка в начале проекта заводит в дебри а затем и тупик. Вот расскажите, UserDead, с чего Вы решили передавать команды строковыми переменными? 
Если заходить с этой точки зрения. То строковыми переменными лучше не передавать команды, а макрос(группу команд выполненых последовательно )Мол если произошло такое событие, то выполнить такой макрос, который размещен в PROGMEM.

 Но это уже заводит нас в концептуальное программирование. Программирование через создание концепций.

Logik
Offline
Зарегистрирован: 05.08.2014

Это заводит нас в пи... Потому как к макросам потребуеися дофига всего лишнего.

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не понял: квон предлагает концептуальный проходной двор устроить из устройства что ли... Всю жись от инъекций защищались и на тебе, оказывается это модная вещь из коллекции "Весна-2018".

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Нормально все . пишется некое ядро. А потом уже на месте с помощью макросов дотачивается до реальной конструкции. Правда тогда надо свой собственный язык для макросов разрабатывать. Но зато новый полет мысли в ардуиностроении.

sadman41
Offline
Зарегистрирован: 19.10.2016

Предлагаю на вход ардуине передавать инструкции честного Си. Это достаточно концептуально?