Приветствую! В озмикла такая ситуация: необходимо написать UDP клиент на СИ, а сервер на делфи.. В общем надо передадать просто 1 структуру по сокетам. Но делфи что-то не так ловит полоченную датаграмму. Я написал клиент и сервер на си - все пашет отлично. Но к этому адскому делфи чтото не прокатывает Вот структура для передачи: Код (Text): typedef struct _tag_bot_info{ BOOL s_ready; BOOL lan_modem; // true - LAN, false - modem BYTE os_type; WORD s_port; WORD bot_version; WORD cpu_speed; WORD total_ram; WORD ie_version; // LOBYTE - major; HIBYTE - minor version DWORD uptime; // minutes since startup } bot_info; на делфи так: type bot_info = record s_ready: boolean; lan_modem: boolean; // true - LAN, false - modem os_type: byte; s_port: word; bot_version:word; cpu_speed: word; total_ram: word; ie_version: word; // LOBYTE - major; HIBYTE - minor version uptime: dword; // minutes since startup end; Вот таким макаром пытаюсь получить датаграмму из делфи: ... var buff: bot_info; ... r := recvfrom(hServerSocket, buff, sizeof(buff), 0, sin, fromlen); ... но приходит чепуха... в то время как на си: recvfrom(s, (char*)&buff, sizeof(buff), 0, (SOCKADDR*)&rem, &len); все отлично проходит! Кто-нить тут шарит в этом "адском" делфе? Что я делаю не правильНо? Спасибо!
Может быть проблема в делфийском выравнивании полей по границам слов ? Попробуй директиву компиляции ... type bot_info=packed record ... Она отключит выравнивание P.S. И кстати boolean в Делфи - однобайтовый
Спасибо! Трабл был действительно в размерности типов BOOL и boolean! А директива packed кстати, наоборот портит все... она уменьшает размер делфийской струкруры на 3 байта!! Получается 17 байт вместо 20! OLS Ты кстати не знаешь аналога этой директивы для си ? Был бы очень благодарен, т.к. сжатие даже на 3 байта для меня довольно критично.. --zm
Кстати, что ты сделал : взял в Делфи 4-байтный тип или в С 1-байтный ? (в первом случае тебе директива никак не поможет - сжимать нечего)
2 MoKC0DeR Повтори по отношению к моей структуре плиз. Не очень понял как применить это.. 2 OLS Я конечно же в СИ заменил BOOL на 1-обайтный BYTE
ZeroMemory Дружеский совет: в обменных форматах записей\структур следует 1) избегать использования специфических типов переменных, 2) самому контролировать выравнивание глазками-ручками. Например, в Delphi тип boolean является generic, implementation dependence типом. Это означает, что борманы оставляют за собой право в будущем использовать любое физическое представление для этого типа. И хотя на деле это лишь страшилка (как был он байтом много лет назад, так и остается по сей день), тем не менее в обменных форматах лучше использовать fundamental типы фиксированного размера ByteBool или лучше просто byte, т.к. в дельфях еще и представление true отличается от С и бэйсика (в паскале 1, а в С xF..Fh). А вот что реально изменилось за давнюю историю паскаля и дельфи, так это представления типов integer (c 2 байт на 4) и real (c нестандартных 6 байт на стандартный 8 байт double). Обжегшись в свое время на молоке, я с тех пор для обмена (длл, файлы и т.п.) использую только типы фиксированного размера (fundamental). В случае когда важен размер и компактность структуры данных лучше самому следить за выравниванием. В дельфях для этого первым делом отключаем выравнивание директивой packed. Можно также использовать директивы компилятора $A- $A+: перед объявлением структуры отключаем, затем включаем (аналогичные директивы должны быть и в Си). Затем сами обеспечиваем выравнивание выбирая соответствующий тип и порядок следования полей и добавляя reserved байты. По общему правилу все word'ы должны быть выравнены на 2, dword'ы на 4 и размер записи д.б. кратен 4. Теперь смотрим на твою запись: вначале идут 3 байта и сбивают выравнивание всех последующих word и dword - не хорошо получается, вот тебе заботливый компилятор 3 байта и вставил. Можешь их сам вставить - будет один резервный байт и один ворд - может пригодиться в будущем. А если тебе каждый байт дорог, то придется что-то упаковать. К примеру первые два була можно заменить на один байт Flags с флагами s_ready = 1 и lan_modem = 2. Иногда просто порядок полей нужно правильно выбирать, например word;dword;word это не правильно, а dword;word;word - OK. В твоем случае то же: можно и не отключать выравнивание, а переставить dword первым, а все байты в конец - тебе то не все ли равно в каком порядке они идут.