Boriska
Помогающий
Offline
|
|
« : 09-09-2021 09:08 » |
|
Привет форумчане. Есть контроллер STM32. И у него есть библиотеки старая SPL и новая HAL. Предствалены они в виде хидеров и сырцов. Захотел я работать с двумя, а там в хидерах масса повторных определений. Редактировать как-то хидеры от производителя не хочется. вставил я межу ними свой файл с отменой повторных определений. #include "oldlibrary.h" #include "myundefinefile.h" #include "newlibrary.h"
ну и там повставлял #undef повторноеопределение1 #undef повторноеопределение2 #undef повторноеопределение3
поборол, но там еще оказались повторные typedef
typedef имятипа1.... попробовал #undef имятипа1 не фурычит и ничего толгового не придумал. Подскажите кто знает пожалуйста.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 09-09-2021 14:39 » |
|
Boriska, привет. Включай заголовки разных библиотек исключительно в разные единицы трансляции. Тогда пересечений не будет
Добавлено через 43 секунды: язык то какой ? Си или C++ ? Стандарт какой?
|
|
« Последнее редактирование: 09-09-2021 14:40 от Алексей1153 »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #2 : 09-09-2021 20:43 » |
|
Что там повторно определяется и где? Я такого не встречал. Обе библиотеки можно использовать совместно. Спутал с LL, с SPL все возможно.
Леш, там чистый С. Компиляторы разные, в зависимости от среды, но как минимимум C99 поддерживается. Особенность embedded разработки в том, что нароют древние библиотеки или старый проект и пытаются скрестить с современной средой, а не прет.
|
|
« Последнее редактирование: 09-09-2021 20:48 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 10-09-2021 03:49 » |
|
RXL, если чистый Си - то сам Страуструп велел в разные cpp заинклудить и наружу пробросить по плюснутому ) Оно взлетит. Сомневаюсь, что там в исходниках C11-е несовместимости с C++ - м встретятся, если проекты древние Добавлено через 3 минуты и 41 секунду:мне если попадается код на Си, но при этом мне необходимо его заюзать - я только так и поступаю, без всяких экспериментов. Потому что там обязательно каша будет Добавлено через 58 секунд:ещё "забавно" бывает по ним статическим анализатором пройтись, сразу волосы дыбом
|
|
« Последнее редактирование: 10-09-2021 03:54 от Алексей1153 »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #4 : 10-09-2021 06:23 » |
|
Ну не совсем так. Библиотека таки SPL и HAL. LL я еще не смотрел. Написаны они на С. Но в среде можно подключить С++, для пользовательских нужд. Что там повторно определяется и где? . Ну вот пример повторного typedef Error[Pe256]: invalid redeclaration of type name "GPIO_InitTypeDef" (declared at line 148 of "H:\STM\Projects\Projects\IAR\First\SPL\inc\ H:\STM\Projects\Projects \IAR\First\HAL\inc\stm32f4xx_hal_gpio.h 63 stm32f4xx_gpio.h")
с повторным дефайном констант и макроссов я поборолся как писал выше #undef IS_PWR_STOP_ENTRY #undef IS_GPIO_SPEED #undef IS_EXTI_LINE #undef IS_EXTI_MODE #undef IS_EXTI_TRIGGER #undef IS_I2S_MCLK_OUTPUT #undef IS_I2S_AUDIO_FREQ #undef IS_GPIO_PIN #undef IS_GPIO_MODE #undef IS_SPI_MODE и др....
Как видите это SPL и НAL Особенность embedded разработки в том, что нароют древние библиотеки или старый проект и пытаются скрестить с современной средой, а не прет. Обижаете поставил Cube с сайта производителя, взял оттуда обе библиотеки, поставил IAR и решил приладить обе и простейшую main. Вот какой стандарт С++ не указан, С++ и С++ with IAR extentions
|
|
« Последнее редактирование: 10-09-2021 06:35 от Boriska »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #5 : 10-09-2021 06:34 » |
|
Алексей Boriska, привет. Включай заголовки разных библиотек исключительно в разные единицы трансляции. Тогда пересечений не будет можно чуть расширить ответ, как это делается.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 10-09-2021 06:44 » |
|
Boriska, что-то вроде: main.cpp int main() { } my_wrapper_SPL.cpp #include .... всё для SPL .... my_wrapper_HAL.cpp #include .... всё для HAL .... Добавлено через 1 минуту и 8 секунд:далее идёт гемор по вкидыванию в main.cpp всего необходимого при помощи extern (это можно как раз в my_wrapper_SPL.h и my_wrapper_HAL.h разместить, которые нужно включить в остальные cpp) Добавлено через 4 минуты и 14 секунд:и, да, каждой библиотеке во вропперах свой namespace полезно будет сделать
|
|
« Последнее редактирование: 10-09-2021 06:51 от Алексей1153 »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #7 : 10-09-2021 08:37 » |
|
Алексей++ там же в этих хидерах, рассматривая как дизэблится assert напоролся на такое выражение #ifdef USE_FULL_ASSERT
/** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) #endif /* USE_FULL_ASSERT */
собственно ((void)0); попробовал IAR игнорит, студия VS17 тоже. под правило раскрутки https://docs.microsoft.com/en-us/cpp/c-language/interpreting-more-complex-declarators?view=msvc-160не подпадает. Раскрутите ((void)0); на человеческий ?
|
|
« Последнее редактирование: 10-09-2021 08:49 от Boriska »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 10-09-2021 10:18 » |
|
Boriska, (void) выражение; - всего лишь "делание вид", что неиспользуемый результат выражения используется то есть, в данном случае - это будет просто ничего не делающий макрос Добавлено через 1 минуту и 47 секунд:в C++11 и старше рекомендуется заменять на std::ignore=выражение; https://en.cppreference.com/w/cpp/utility/tuple/ignore
|
|
« Последнее редактирование: 10-09-2021 10:22 от Алексей++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 10-09-2021 21:13 » |
|
Попробую еще раз объяснить суть раздельной компиляции: разные модули (.c файлы) работают только с одной версией системной библиотеки, интерфес библиотек описан в обном или нескольких заголовках (.h файлы), где, как сказал Леха, объявлены только структуры и прототипы функций, причем последние предварены extern, аналогично с глобальными переменными. При компиляции получаются объектые (.o) файлы. Они содержат эспортируемые и импортируемые функции. При линковке объектых файлов в бинарь разные модули предоставляют (экспортируют) свои символы и импортируют чужие. Тут главное, чтобы не было одноименных экспортируемых имен в разных модулях. Т.е. разделение на модули гарантированно разделяет макросы и типы, но ничего не может поделать с функциями. Неэкспортируемые функции объявлены со static, это означает вилимость только внутри модуля.
GPIO_InitTypeDef — это объявление типа через typedef struct. В HAL используется в типе параметра функции. void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) Раздельная компиляция поможет обойти данную ошибку. Но инициализация GPIO должна быть одна, в одном модуле, а не в нескольких модулях, иначе будет несогласнованность.
Все это очень скользкая дорожка. По хорошему, надо к одной системной библиотеке сводить.
Добавлено через 2 минуты и 55 секунд: Алексей++, тут не плюсы, все на чистом Си. Не С++99, а С99. Например, в отличии он ANSI С, в C99 менее строгое объявление переменных, не только в начале функции или блока.
|
|
« Последнее редактирование: 10-09-2021 21:16 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #10 : 24-09-2021 12:22 » |
|
Привет. Поясните как вы лихо связали (void) выражение; с std::ignore=выражение; Плюс там было ((void)0) это ((void)литерал)
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 24-09-2021 12:50 » |
|
Boriska, это вопрос Лехе?
SPL и HAL делают одно и тоже, просто они созданы в разное время. Я думаю, что нужно погуглить гайд миграции с SPL на HAL и все привести к единой библиотеке.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #12 : 24-09-2021 13:29 » |
|
Народ который давно сидит пользуется или CMSIS или SPL или LL или HAL. Все тяжелее и тяжелее. Это была моя заморочка иметь под собой все четыре и дергать ту которая нужна мне в проекте для конкретной задачи - как-то хочется простое делать на простой библиотеке допустим CMSIS (на регистрах), а если запись на SD карту, в подробности протокола записи SD карты не вникать и сделать это на HAL.
Ну Лехе не Лехе, а не совсем понятно объяснение.
|
|
« Последнее редактирование: 24-09-2021 14:15 от Boriska »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 24-09-2021 18:19 » |
|
Boriska, выражение - это какое угодно rvalue-выражение. Приведение неиспользуемого выражения к (void) или присвоение его к std::ignore даёт знать компилятору и анализатору, что тут не требуется выдавать предупреждения о неиспользованной переменной или о выражении, не дающем эффекта #include <iostream> #include <tuple>
[[nodiscard]] int func() { return 1; }
int main() { func(); //предупреждение (void)func(); //ок std::ignore=func();//ок 1; //предупреждение (void)1; //ок std::ignore=1;//ок
return 0; }
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #14 : 26-09-2021 20:50 » |
|
Boriska, в итоге, получилось?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #15 : 19-11-2021 08:40 » |
|
Привет. Пока отложено (работа пока заедает), но возвращение обязательно (микропроцесоры это для души), и обязательно напишу. Да, кстати, vs ключи компилятора, как вывести препроцессированный файл.
|
|
« Последнее редактирование: 19-11-2021 08:42 от Boriska »
|
Записан
|
|
|
|
|