Jump to content
-=FISHER=-

Перевести код с C на C++

Recommended Posts

Всем привет!

Помогите пожалуйста перевести код написанный на С в С++.

Для понимания контекста, я приведу бОльший кусочек кода, задача его в том чтобы приняв строку по USART запустить определенную функцию, причем часть имени функции будет присутствовать в принимаемой строке. Этот код прекрасно компилируется и работает в Atmel Studio 7, но возникла необходимость скомпилировать его в среде Arduino IDE. Однако компилироваться он не хочет, вылетая с ошибкой (как я понял) что часть когда написана в синтаксисе С, а не C++.

Скрытый текст

#define CMD_CNT  8 // количество команд
#define CMD(n) { .func = cmd_ ## n, .cmd = # n } // макрос для удобства описания элемента массива

/*Покажу на примере. Макрос CMD(BR) развернется в такую строку: {.func = cmd_BR, .cmd = "BR"}
  
Это запись инициализации стркутуры. С точками - имена полей (расширение GCC),
потом начальное значение. ## - команда конкатенации препроцессора, просто склеивает то,
что слева от нее с тем, что справа до первого символа-разделителя (запятая, пробел).
# - команда препроцессора преобразования литерала в строку, по сути обрамляет двойными кавычками то,
 что справа от нее до первого разделителя.
*/

#define STR_LEN  35 //максимальная длина строки команды по USART
static volatile uint8_t rx_pos; // позиция приема
static char obd_string[STR_LEN]; // принимаемая строка
static volatile uint8_t rx_complete; // флаг готовности строки

char sep [5]; //разделитель команды
static char obd_cmd[6]; //Переменная, в которую будут заноситься начальные адреса частей
static char transmit_cmd[100]; //отправка расшифрованной команды
char cmd_len; //длинна команды

typedef void (*handler_t)(char *obd_str); // тип "функция-обработчик строки"

// тип структуры для описания обработчика команды
typedef struct
{
  handler_t func; // функция-обработчик
  char    cmd[7]; // команда, состоит из двух символов и нуль-терминатора
} hndlr_t;

hndlr_t handler[CMD_CNT] = // массив структур команд
{
  CMD(ATSP0), //автоматическое определение протокола
  CMD(010C), //обороты двигателя
  CMD(0105), //температура охлаждающей жидкости
  CMD(0111), //дроссель
  CMD(010F), //температура воздуха на впуске
  CMD(010B), //давление во впускном коллекторе
  CMD(DF), //задержка выключения
  CMD(SY) //задержка выключения
};

void cmd_ATSP0(char *obd_str) //автоматическое определение протокола
{

}

void cmd_010C(char *obd_str) //обороты двигателя
{

}

void cmd_0105(char *obd_str) //температура охлаждающей жидкости
{

}

void cmd_0111(char *obd_str) //дроссель
{

}

void cmd_010F(char *obd_str) //температура воздуха на впуске
{

}

void cmd_010B(char *obd_str) //давление во впускном коллекторе
{

}

void cmd_DF(char *obd_str) // прототип обработчика команды SG
{

}

void cmd_SY(char *obd_str) // обработчик команды SY (синхронизация)
{

}

 

А вываливается, конкретно вот на этом участке кода с комментарием: comp:106:1: error: C99 designator 'cmd' outside aggregate initializer.

Скрытый текст

hndlr_t handler[CMD_CNT] = // массив структур команд
{
  CMD(ATSP0), //автоматическое определение протокола
  CMD(010C), //обороты двигателя
  CMD(0105), //температура охлаждающей жидкости
  CMD(0111), //дроссель
  CMD(010F), //температура воздуха на впуске
  CMD(010B), //давление во впускном коллекторе
  CMD(DF), //задержка выключения
  CMD(SY) //задержка выключения
};

 

Скрытый текст

432.JPG.885f27227354895ec7693eb8f998bc6b.JPG


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
2 часа назад, -=FISHER=- сказал:

перевести код написанный на С в С++.

Да будет Вам известно, что С++ полностью включает в себя синтаксис языка С.

Share this post


Link to post
Share on other sites

Интеллектуальные ключи верхнего плеча семейства PROFET™+2 12V от Infineon

омпания Infineon представила новое семейство защищенных силовых ключей PROFET™+2 12V. Изделия объединяют в себе функции диагностики и различные защиты. Ключи PROFET™+2 12V имеют одно из самых низких в отрасли сопротивлений в открытом состоянии RDS(ON) (от 2,6 мОм) и выпускаются в миниатюрном корпусе TSDSO-14 с шагом выводов 0,65 мм. Благодаря функции ReverseON все семейство соответствует строгим требованиям по защите от обратной полярности питания, впервые реализованной в одном чипе.

Подробнее

2 часа назад, -=FISHER=- сказал:

перевести код написанный на С в С++

C++ это по сути тот же С только с "классами" то есть С++ это ООП, а С это процедурный язык.

В вашем случае скорее всего как пример

эта строка

CMD(ATSP0), //автоматическое определение протокола


должна как то вызывать эту функцию

void cmd_ATSP0(char *obd_str)


Но это не точно, это как предположение.

Share this post


Link to post
Share on other sites

Вебинар «Экосистема MEAN WELL. Решения для любых задач электропитания» (20.05.2021)

Приглашаем 20 мая на вебинар, посвященный линейке поставок компании MEAN WELL и ее подходу к производству источников питания — как экосистемы продукции и услуг, которая позволяет подобрать оптимальный источник питания для любых задач электропитания. Рассмотрим весь спектр выпускаемой продукции MEAN WELL в области AC/DC-, DC/DC- и DC/AC-преобразователей с подробным разбором интересных и уникальных новинок, их применении и многое другое.

Подробнее

Posted (edited)
4 часа назад, LiVit сказал:

не поможет?

Описанный там пример включает знаки "=" которые просто убрали всё заработало. У меня нет знаков равно...

 

3 часа назад, kt118 сказал:

Но это не точно, это как предположение.

Да именно так оно и работает))) меня интересует как сделать чтобы скетч скомпилировался.

4 часа назад, Alex сказал:

Да будет Вам известно

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

1931860013_.JPG.a3718537114e76464b3c3e42ed17576d.JPG

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Изолированный помехоустойчивый трансивер RS-485 ADM2795E Analog Devices

Оборудование на промышленных предприятиях подвергается воздействию кондуктивных, излучаемых и магнитных помех, а также скачков напряжения, и должно соответствовать требованиям стандартов серии IEC 61000. ИС ADM2795E производства Analog Devices сертифицирована на устойчивость к ЭСР по стандарту IEC 61000-4-2, и подходит для эксплуатации в жестких условиях. Представляем результаты испытаний на устойчивость к кондуктивным и излучаемым радиопомехам, а также устойчивость к магнитному полю.

Подробнее

Но, Вы же прекрасно понимаете, в чём проблема с кодом ? И устранить её, понимая код, не составит никакого труда.
В простейшем случае - выкинуть к чертям этот макрос и заполнить таблицу ручками.
Да и вообще, не понятно, к чему этот выпендрёжный финт ?  Ради экономии 5-ти байт исходного кода ?

Share this post


Link to post
Share on other sites

И ещё. Вы в курсе, что строка, типа "бла-бла", логически является константой ? По крайней мере, её длина (при создании копии в RАМ). И принимая на неё ссылку (указатель) в функции, необходимо указывать, что Вы изменять её не собираетесь.
В противном случае, компилятор вправе Вас обматерить.

Share this post


Link to post
Share on other sites
Posted (edited)

Скомпиллировалось без проблем чисто С-ным компиллятором для армов. И MinGW под винду тоже. Нет там ничего криминального. А "синтаксисом" С++ тут и не пахнет. Ищите проблему где-то в другом месте.

Навскидку советую обратить внимание на то, где находится <hndlr_t handler[CMD_CNT]> по отношению к объявлениям/определениям функций, адреса которых присваиваются его полям при инициализации. Он должен находится или после всех функций (после <cmd_SY> в вашем примере), либо их прототипы должны быть объявлены в самом начале модуля.

Если не поможет, то под капотом у ардуины находится обычный gcc-ный компилятор. У него есть такая замечательная опция "-E", которая позволяет выполнить препроцессинг модуля и посмотреть что получается в итоге с модулем. Вызывается как-то так: <${ПУТЬ-САМУРАЯ}\avr-gcc.exe -E test.c>, где <test.c> путь к вашему файлу. Он прямо в консоль должен выплюнуть результат, можно будет всё просмотреть и проанализировать.

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

 

Edited by El-Shang

Share this post


Link to post
Share on other sites
Posted (edited)
13 часов назад, -=FISHER=- сказал:

я пришел к выводу что некоторые отличия всё таки есть

откуда вы пришли к выводу :) ? У вас там написано, что используется расширение GCC. Расширение GCC это не С и не С++, это какая то самодеятельность GCC, которая не будет обрабатываться в любом другом компиляторе. Поэтому решением является НЕ использовать не стандартные расширения компиляторов, если вы хотите чтобы код компилировался в разных компиляторах, это не имеет отношения к С/С++, это особенность конкретного компилятора (несовместимость по допустимым конструкциям кода), точнее использование этой особенности в коде.

Edited by ruhi
дополнил

Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


Link to post
Share on other sites

Вообще, интересная картина нарисовывается. Человек выкладывает код, в котором есть коммент с наиподробнейшим описанием макроса. И тут же сразу задаёт вопрос по этому макросу :lol:

Share this post


Link to post
Share on other sites

Никакое это не расширение. Инициализации структуры в виде <struct a b = {.c = 1, .b = 2}> если верить этому источнику абсолютно стандартное средство начиная с C99. С великой долей вероятности автор просто чего-то недокопировал, недообъявил, забыл перенести какие-то определения, объявленные на уровне конфигурации проекта или ещё что-то подобное.

И потом, если оно работает в студии, то зачем тащить в ардуину? Разумнее как раз наоборот. Легче интегрировать что-то простое в что-то более сложное, а это как раз про них. У ардуины-то используется упрощенный (читай подмножество) С, если я всё правильно представляю. Правда, стандартные библиотеки содержащие всякие там digitalRead и digitalWrite не заедут, но там всё не так уж и сложно, чтобы не набросать замену. Но то такое. Каждый для себя решает.

Share this post


Link to post
Share on other sites
17.04.2021 в 16:50, Alex сказал:

Да будет Вам известно, что С++ полностью включает в себя синтаксис языка С.

Правильно только с  немного друими командами и С++ больше команд

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...