1

Тема: Кодировка символов в версиях для ОС Windows и Linux

Здравствуйте.
Заметил особенность в размерах символов между версиями для ОС Windows и Linux.
При кодогенерации использование типа wchar_t приводит к размеру 2 байта в Windows. С другой стороны, ОС Linux считает размер wchar_t как 4 байта.

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

Пробовал решить проблему с помощью изменения заголовка GraphLib.h. А именно изменением строк:

#include <wchar.h>
typedef wchar_t char_un;   /* для Unicode строк */

=>

#include <uchar.h>
typedef char16_t char_un;   /* для Unicode строк. Измененный тип wchar_t на char16_t */

или

typedef unsigned short int char_un;   /* для Unicode строк. Измененный тип wchar_t на unsigned int */

При замене префикса с "L" на "u" по-началу все отображалось хорошо. Но потом возникла новая проблема. В одном из проектов у графического объекта используется функция форматирования текста:

format("%02d:%02d:%02d", 1, 12, 3)

При кодогенерации это приводит к вызову C-функции vswprintf, которая подразумевает использование только типа wchar_t:

int vswprintf (wchar_t * ws, size_t len, const wchar_t * format, va_list arg );

Графический симптом проблемы выглядит как отображение строки %02d:%02d:%02d на экране.

Подскажите, пожалуйста, как можно сделать размер входной структуры одинаковым в обоих ОС и что бы при этом на экране корректно отображался форматированный текст?

Заранее спасибо за ответ.

2

Re: Кодировка символов в версиях для ОС Windows и Linux

Здравствуйте!
Нам кажется, что решить эту проблему со стороны САПР вряд ли получится. Здесь, вроде бы, всё правильно. Если в одной ОС функция vswprintf в качестве строки принимает массив символов по 2 байта, а в другой по 4, то тут ничего не поделаешь, и необходимо передавать массив символов такого размера, который требуется для vswprintf в данной конкретной ОС. Т.е. это должны быть два отдельно сгенерированных кодогенератором и скомпилированных программных кода.
Давайте попробуем подойти к проблеме с другой стороны. Опишите, пожалуйста, более подробно, что и как вы делаете, а также, что у вас не получается при создании платформонезависимого решения.

3

Re: Кодировка символов в версиях для ОС Windows и Linux

Мы стараемся настроить кодогенерацию максимально похожей для двух ОС: Windows и Linux. Идеальным случаем (но не обязательным) считаем создание такого профиля кодогенерирования, что бы сгенерированый единожды код можно было собрать в любой обозначенной ОС в виде библиотеки (.so для Linux; .dll для Windows).
Поскольку отрисовка GL-объекта предполагается удаленно относительно модели расчета параметров входной структуры, то требуется состыковать их между собой. Модель должна собрать в входную структуру набор параметров для GL-объекта. Отображение должно получить входную структуру и перерисовать GL-объект.
Во время выполнения каждая из сторон не знает на базе какой ОС работает другая сторона. Например, модель может работать на базе ОС Linux, а отображение на ОС Windows. Связь между отображением и логикой может быть по сети.
Разница в размерах одного символа приводит к невозможности корректной передачи структуры, так как при этом сдвигаются поля входной структуры.
Нам удалось сократить различия в профилях кодогенерации до следующих вводных:
1) Изменили заголовок GraphLib.h (для обоих профилей):

#include <wchar.h>
typedef wchar_t char_un;   /* для Unicode строк */

=>

typedef unsigned short int char_un;   /* для Unicode строк. Измененный тип wchar_t на unsigned int */

2)Заменили «префикс строк» для профиля Linux c «L» на «u». Профиль Windows использует префикс «L».

Это позволило генерировать код схожим образом для Linux и Windows. Позволило устранить разницу в размерах символов (в обоих ОC по 2 байта на символ).
Удается правильно отображать статичный текст (заданный заранее). Удается задавать и корректно отображать динамичный текст (являющийся, например, параметром входной структуры GL-объекта).
Возникла всего одна проблема, которую пока не получилось решить. Она связана с текстом, который проходит процедуру форматирования где-то в проекте. Например, когда в самом проекте используется код такого вида:

format("%02d:%02d:%02d", 1, 12, 3)

4

Re: Кодировка символов в версиях для ОС Windows и Linux

Спасибо за подробное объяснение!
Применение префикса ‘u’ для строк по стандарту С++11 создаёт строки с символами в кодировке UTF-16, а это некорректно по отношению к функциям стандартной библиотеки языка С в ОС Linux, которые, по сути, ожидают символы в кодировке UTF-32. И у нас нет никаких идей, что с этим можно сделать в рамках языка С. И это касается не только функции vswprintf, но и других функций работы с Unicode строками, используемых нами в файле GraphLibImpl.c, например, wcscpy, wcscmp, wcsstr и др.. Т.е. проблемы могут появиться не только при форматировании строк в САПР, но и при применении других встроенных функций вычислителя САПР, предназначенных для работы со строками.
Всё, что приходит на ум, это запись моделью во входную структуру размера символов сохранённых в неё строк, и конвертация строк отображающей частью, если размер символов не совпадает. Но это всё, к сожалению, потеря производительности.