2013-03-15 1 views
0
unsigned short* pname = (unsigned short*)(buf + buf_offset);/*sequence problem?*/ 
unsigned short pointer_offset = ntohs(*pname) & COMPRESSION_MASK; 

Здесь buf_offset == 0. содержимое buf равно [c0] [0c]. Однако * pname является [0x0cc0]. В чем проблема? Спасибо.Последовательность байтов, когда cast char * в unsigned short * и разыменование?

+1

Какой тип 'buf'? Можете ли вы показать немного больше кода, чтобы сделать это более понятным? –

+0

ntohs() меняет порядок байтов – gabriel

ответ

0

Как уже отмечалось, код, который вы выложили не является переносимым. Дело не только в причине судьбы. Литье от char * до unsigned short * также может вызывать bus errors из-за неправильного выравнивания. Кроме того, могут быть биты заполнения в unsigned short, которые приводят к неправильной работе вашей программы, или unsigned short может быть меньше или больше, чем «2 байта» в зависимости от CHAR_BIT и вариантов реализации. Общая проблема заключается в внутреннем представлении типов, и вы можете избежать этой проблемы, используя операторы, которые ведут себя одинаково независимо от внутреннего представления. Возможно, вы имели в виду:

unsigned short offset = (unsigned char) buf[0]; 
offset *= (UCHAR_MAX + 1); 
offset += (unsigned char) buf[1]; 
offset &= COMPRESSION_MASK; 

Если вы хотите большой эндиан, вы должны явно указать, что хотите. Умножая buf[0] и добавляя buf[1], я указываю, что buf[0] является более значительным, чем buf[1], поэтому я явно указываю, что хочу большой endian. Умножения и дополнения работают одинаково во всех реализациях C, и нет проблем с выравниванием.

реверсивного преобразования:

unsigned char buf[2] = { offset/(UCHAR_MAX + 1), offset % (UCHAR_MAX + 1) }; 

Было бы хорошо, чтобы увидеть больше кода, написанного без заботы о внутреннем представлении!

+0

Спасибо. Это то, что мне нужно! – user2172495

+0

@ user2172495: Я только что заметил ошибку в моем коде. Обратите внимание на изменения для его исправления. – Sebivor

0

Это зависит от вашей платформы, big-endian/little-endian вам следует изменить порядок байтов.

#ifdef _BIG_ENDIAN_ 
    // revers bytes order 
#endif 
+0

Как проверить, является ли моя платформа БОЛЬШОЙ или маленькой Ending? Моя чаша - это интеллект. OS - это окно 8. – user2172495

0

ntohs() обменивает порядок байт в большой Endian

+0

В buf 0xc0 находится в нижнем адресе памяти. Тем не менее, после того, как вы выбрали беззнаковое короткое замыкание, 0xc0 находится в адресе высокой памяти (маленький конец). Это странно? – user2172495

0

Как упоминалось Габриэля,

The ntohs() преобразует u_short от того, TCP/IP сеть байт для размещения порядка следования байтов (который мало-младшему на процессорах Intel).

Функция ntohs возвращает значение в порядке байтов хоста. Если переданный параметр уже находится в порядке байтов хоста, то эта функция изменит его. Это зависит от приложения, чтобы определить, должен ли порядок байтов быть отменен.

+0

Да, моя программа предназначена для преобразования байтов ответа DNS в значение хоста. И кажется, что другой DNS отправляет другой ответ на заказ. – user2172495