sonycman 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Компилятор RealView 4.0.0.524 из пакета MDK3.70. C++. Что-то не слушается меня компилер, то ли я не так пишу, то ли багу нашёл. Исходник: #define USB_STRING_DESCRIPTOR_TYPE 3 #define MANUF_STRING L"Sonycman Production" #define PROD_STRING L"Sonycman Mass Storage Drive" #define SERIAL_STRING L"123456789ABC" typedef __packed struct { byte length; byte descriptor_type; word languageID; } USB_STRING_ID_DESCRIPTOR; typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(MANUF_STRING)/2]; } USB_STRING1_DESCRIPTOR; typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(PROD_STRING)/2]; } USB_STRING2_DESCRIPTOR; typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(SERIAL_STRING)/2]; } USB_STRING3_DESCRIPTOR; typedef __packed struct { USB_STRING_ID_DESCRIPTOR s0; USB_STRING1_DESCRIPTOR s1; USB_STRING2_DESCRIPTOR s2; USB_STRING3_DESCRIPTOR s3; } USB_STRING_DESCRIPTOR; и инициализация: const USB_STRING_DESCRIPTOR CUSB::strings = { sizeof(USB_STRING_ID_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, 0x409, //language ID sizeof(USB_STRING1_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, MANUF_STRING, sizeof(USB_STRING2_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, PROD_STRING, sizeof(USB_STRING3_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, SERIAL_STRING }; Так вот, члену strings присваиваются такие данные: 0x080046f9: 04 03 09 04 2a 03 00 53 00 6f 00 6e 00... Но откуда взялся в запакованной структуре явно пэддинг байт (выделен жирным)?! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
forever failure 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба wchar_t text[sizeof(MANUF_STRING)/2]; /*<-- здесь точно требуется массив из двух байт ?*/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба А попробуйте простую кондовую #pragma pack(1) вместо этих многочисленных и совсем уж плохо переносимых __packed Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба wchar_t text[sizeof(MANUF_STRING)/2]; /*<-- здесь точно требуется массив из двух байт ?*/ Там массив из двухбайтовых слов - строка в юникоде. А попробуйте простую кондовую #pragma pack(1) вместо этих многочисленных и совсем уж плохо переносимых __packed Щаз попробую :) А эта прагма будет относиться только к сразу следующей за ней структуре, или сразу до конца файла? Эм, попробовал - без результата, лишний нулевой байт остаётся... Хотя с прагмами прикольно - у меня SlickEdit не понимает (__packed), и теперь можно его убрать! С другой стороны, прагма работает до конца файла, приходится ставить лишнюю pragma pack(), чтобы выравнивание вернулось к состоянию по умолчанию... Проблема решается, если структуре strings добавить квалификатор align(2) - то есть выровнять её в памяти. Тогда пэддинг не вставляется, и данные генерятся так, как надо. Но это уже, имхо, костыль для обхода бага... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба А эта прагма будет относиться только к сразу следующей за ней структуре, или сразу до конца файла? До конца, или отменяющей прагмы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба 0x080046f9: 04 03 09 04 2a 03 00 53 00 6f 00 6e 00... Но откуда взялся в запакованной структуре явно пэддинг байт (выделен жирным)?! Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t. __packed вообще-то прекрасно работает в RVDS'е. padd здесь ни один компилятор не вставит. Сами подумайте тип wchar - 2 байта. Какого лешего его размещать с нечетного адреса? А в вашем примере если допустить что выделенный 00 это padd байт, то wchar располагается как раз по нечетному смещению "0x7". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t. Ничего подобного - сам стринг должен быть таким: 53 00 6f 00 6e 00... RVDS 2.2 создает корректную структуру (в плюсовом режиме правда не смотрел): 0x0000a4c4 04 03 09 04 2A 03 53 00 6F 00 6E 00 79 00 63 00 ....*.S.o.n.y.c. 0x0000a4d4 6D 00 61 00 6E 00 20 00 50 00 72 00 6F 00 64 00 m.a.n. .P.r.o.d. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t. __packed вообще-то прекрасно работает в RVDS'е. padd здесь ни один компилятор не вставит. Сами подумайте тип wchar - 2 байта. Какого лешего его размещать с нечетного адреса? А в вашем примере если допустить что выделенный 00 это padd байт, то wchar располагается как раз по нечетному смещению "0x7". Ноль должен идти уже после 0х53, но никак не до! В пакованной структуре wchar_t может начинаться с нечётного адреса - на то она и запакованная! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Ноль должен идти уже после 0х53, но никак не до! В пакованной структуре wchar_t может начинаться с нечётного адреса - на то она и запакованная! В упакованной структуре padding'и отсутствуют как класс. Если предположить что что-то не так с упаковкой (компилер не понял слово __packed), тогда получается неувязочка с нечетным смещением. Ничего подобного - сам стринг должен быть таким: может какой-то атрибут применен, который перевернул строку в bigendian. Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба sonycman: а данные структуры где смотрите? может какой-то атрибут применен, который перевернул строку в bigendian. Знаете такой атрибут? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Ноль должен идти уже после 0х53, но никак не до! Ну так переверните его и посмотрите что получится. swap16( ...->s1.text[ 0 ] ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Ну так переверните его и посмотрите что получится. swap16( ...->s1.text[ 0 ] ); Напишите +2 по результатам отладки, ага. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Напишите +2 по результатам отладки, ага. Ага, тогда думайте, что это padding дальше и пытайтесь пофиксить его как паддинг. Мне то что. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Компилятор RealView 4.0.0.524 из пакета MDK3.70. C++. В не C++ режиме тоже все нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба может какой-то атрибут применен, который перевернул строку в bigendian. Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем. Весь код перед вами в первом посте. Тут не переворот, а лишний байт, так как вся структура имеет длину на 1 байт больше, чем должна быть. sonycman: а данные структуры где смотрите? Смотрю в отладчике, в режиме симулятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться