Непостижимая проблема с юникодом и фреймворками - PullRequest
0 голосов
/ 14 июня 2011

У меня возникла очень странная проблема ... Следующий тривиальный тестовый код работает, как и должно, если он внедряется в одно приложение Какао , но когда я использую его в одном из моих frameworks , я получаю совершенно неожиданные результаты ...

wchar_t Buf[2048];
wcscpy(Buf, L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len1 = wcslen(L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len2 = wcslen(Buf);

char Buf2[2048];
Buf2[0]=0;
wcstombs(Buf2, Buf, 2048);

// ??? Buf2 == ""
// ??? len1 == len2 == 57, but should be 101


Как это может быть, я сошел с ума?Даже если было повреждение памяти, он не мог повредить все эти значения, выделенные в стеке ... Почему даже wcslen (L "MyWideString") не работает?Изменение тестовой строки меняет ее длину, но это всегда неверно, wcstombs возвращает -1 ...

setlocale () нигде не используется, тестовая строка содержит только ASCII символов, для облегчения портирования я использую опцию компилятора -fshort-wchar , но она отлично работает в случае тестового приложения Какао ...

Пожалуйста, помогите!

Ответы [ 3 ]

0 голосов
/ 21 июня 2011

Я только что проверил это снова с GCC 4.6.В стандартных настройках это работает как положено, давая 101 для всех длин.Тем не менее, с вашим параметром -fshort-wchar я также получаю неожиданные результаты (51 в моем случае и 251 для окончательного преобразования после использования setlocale ()).

Так что я искал запись man для опции:

Предупреждение: ключ -fshort-wchar заставляет GCC генерировать код, который не является двоичным, совместимым с кодом, сгенерированным без этого переключателя.Используйте его для соответствия бинарному интерфейсу приложения, отличному от используемого по умолчанию.

Я думаю, это объясняет это: когда вы ссылаетесь на стандартную библиотеку, вы должны использовать правильный ABI и соглашения о типах,который вы переопределяете с этой опцией.

0 голосов
/ 27 марта 2012

-fshort-wchar изменить ABI компилятора, поэтому вам нужно перекомпилировать glibc, libgcc и всю библиотеку, используя wchar_t.В противном случае wcslen и другие функции в glibc по-прежнему предполагают, что значение wchar_t равно 4 байтам.

см .: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42092

0 голосов
/ 14 июня 2011

Широкая реализация символов в C / C ++ может быть любой, включая 1 байт, 2 байта или 4 байта.Это зависит от компилятора и платформы, на которую вы компилируете.

Возможно, wikipedia - не лучшее место для цитирования, но в этом случае: http://en.wikipedia.org/wiki/Wide_character утверждает, что

... ширина wchar_t зависит от компилятора и может составлять до 8 бит.

и

... широкие символы должны быть 16-битными значениямипод C90 по историческим причинам совместимости.Компиляторы C и C ++, соответствующие стандарту Unicode 10646-1: 2000, обычно принимают 32-битные значения ....

Таким образом, не принимает и использует sizeof(wchar_t).

...