Про gcc и кодировки

Прочитав статью про создание самодельных шрифтов вспомнил про свои мучения. Правда, у меня проблема возникла в тот момент, когда я зашил созданный шрифт и попытался вывести с помощью AVR-ки русские строки, то есть, с кодировками utf-8/win-1251. Про них и пост.

Задача
Есть AVR и желание выводить с его помощью русские строки.
Есть gcc в качестве компилятора, работающий под виндой.
Нет желания городить свою библиотеку для работы с utf-8.
Спрашивается: как?
Сначала я сделал как в VC++: открыл любимый блокнотик, забил туда win-1251, сама строка была задана вот так:


char s[] = {"Тестовая строка"};


Собрал, запустил… мимо.
Ок, пошёл в гугл.
Нашёл страничку.
Поставил опциями компилятора win-1251 на входе и выходе.
Всё сломалось с криком:

"cc1plus.exe: error: no iconv implementation, cannot convert from win-1251 to UTF-8".

Ну, примерно с таким криком.
Дальше я долго гуглил, выяснил таки, что проблема в том, что в винде нет волшебного iconv (libiconv), который есть в линуксе, и что эта самая либа должна быть статически влинкована в gcc.
Нашёл адский тредик, как мужики пытались это сделать.
И наконец таки нашёл страничку с уже готовым gcc.
Ура. Скачал. Обновил.
Дальше просто. Сначала нужно взять свои исходники и сконвертить их в utf-8. На всякий случай. Может и без этого заработает.
Потом поправить строчку с ключиками от gcc:

C:\tools\avr-gcc\bin\avr-g++.exe -mmcu=atmega8515 -finput-charset=UTF-8 -fexec-charset=cp1251 -std=gnu++11 -Os main.cpp -o main.o

Потом запустить сборку, и вдумчиво посмотреть в полученный бинарник.
Дальше открываем .hex файл и убеждаемся, что в нём появились вполне нормальные ASCII коды, которые похожи на строку в win-1251!
Profit!

ЗЫ: Да, найденная сборка gcc имеет одну неприятную особенность: внутри она содержит неправильный avr-size, который не понимает ключик mmcu.

Комментарии (2)

RSS свернуть / развернуть
А ещё лучше не сувать русских строк в код, а пихать их отдельным файлом и вставлять define'ом
А самый верх навыка джедая — делать массив строковых констант и заполнять его из файла линковщиком. Но это сложно. Зато позволяет не только русский текст, но и картинки bmp, файлы wav и прочие ресурсы пихать.
0
  • avatar
  • dekar
  • 10 февраля 2016, 18:27
Мне кажется, что вставить что-либо из внешнего файла можно include-ом. А не define-ом.
Кроме того, препроцессор (обрабатывающий include/define/etc) работает до компилятора. А значит компилятору всё равно придётся как-то рассказать, какая у входного файла кодировка.
Про линковщик. Я не знаю способа, как заставить AVR/gcc прочитать чего-нибудь из бинаря. Ну, кроме функции pgm_read_byte. Но этой функции надо дать адрес. А адресами ведает компилятор, а не линковщик. (Ну, точнее сказать, узнать адрес проще с помощью компилятора, а не линковщика).

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

У меня же есть мелкий микроконтроллер и прошивка. ОСи нет. Ресурсов нет. Функций чтения из файлов нет. Нет даже файловой системы :)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.