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

Приглашаем на вебинар «Умный и безопасный дом от STMicroelectronics – строим вмеSTе!» (23.06.2021)

Приглашаем 23/06/2021 всех желающих принять участие в вебинаре, посвященном проектированию и разработке систем умного дома на базе компонентов STMicroelectronics. Экосистема продукции STMicroelectronics включает в себя как электронные компоненты, так и средства разработки, готовые стеки протоколов и законченные примеры кода. Предлагаемые ресурсы позволят разработчику легко построить каркас системы и быстро создать прототип своего приложения. На вебинаре также расскажем о беспроводных интерфейсах – ведь благодаря поддержке стандартов BLE и ZigBee разработчики смогут при необходимости интегрировать устройства сторонних производителей и создавать открытые системы.
Подробнее

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

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

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

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

эта строка

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


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

void cmd_ATSP0(char *obd_str)


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

Share this post


Link to post
Share on other sites

Тактовые кнопки Panasonic - высококачественная коммутация в миниатюрном исполнении

Panasonic, один из мировых лидеров по производству высококачественных электромеханических компонентов, и Компэл представляют масштабное расширение складской программы. В настоящее время на складе Компэл доступны ведущие серии SMD-тактовых переключателей Panasonic в миниатюрных корпусах. Линейка тактовых кнопок Panasonic отличается многообразием компактных переключателей различных типоразмеров, форм штока и выводов. Переключатели отвечают важнейшим требованиям в ответственных применениях.

Подробнее

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

Решения TE Connectivity для 112 Gbps архитектуры и серверов. Соединители STRADA Whisper

Данная статья является первой из публикаций, описывающих решения компании TE Connectivity для высокоскоростных соединений. Она посвящена соединителям и кабельным сборкам серии STRADA Whisper, главная особенность которых – поддержка работы с технологией PAM-4 и скорости передачи до 112 Гбит/с.
Подробнее

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