Что означает эта строка кода C? - PullRequest
4 голосов
/ 14 ноября 2010

Я конвертирую некоторый C-код в Delphi. Может кто-нибудь объяснить мне, что означает эта строка?

nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
 | ( pBuffer[ 1 ] & 0x00FF );

Вот остальная часть кода для контекста:

USHORT UTIL_htons( USHORT hostshort )
{
 PUCHAR pBuffer;
 USHORT nResult;

 nResult = 0;
 pBuffer = (PUCHAR )&hostshort;

 nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
  | ( pBuffer[ 1 ] & 0x00FF );

 return( nResult );
}

USHORT UTIL_ntohs( USHORT netshort )
{
 return( UTIL_htons( netshort ) );
}
ULONG UTIL_htonl( ULONG hostlong )
{
 PUCHAR pBuffer;
 ULONG nResult;
 UCHAR c, *pResult;

 pBuffer = (PUCHAR )&hostlong;

 if( !pBuffer )
 {
  return( 0L );
 }

 pResult = (UCHAR * )&nResult;

 c = ((UCHAR * )pBuffer)[ 0 ];
 ((UCHAR * )pResult)[ 0 ] = ((UCHAR * )pBuffer)[ 3 ];
 ((UCHAR * )pResult)[ 3 ] = c;

 c = ((UCHAR * )pBuffer)[ 1 ];
 ((UCHAR * )pResult)[ 1 ] = ((UCHAR * )pBuffer)[ 2 ];
 ((UCHAR * )pResult)[ 2 ] = c;

 return( nResult );
}
ULONG UTIL_ntohl( ULONG netlong )
{
 return( UTIL_htonl( netlong ) );
}

Спасибо заранее Боян

Ответы [ 4 ]

4 голосов
/ 14 ноября 2010

Очевидно (все эти определения в верхнем регистре затрудняют чтение), функции меняют внутренний порядок байтов значений, которые занимают 2 или 4 байта.Например:

UTIL_htons(0x1234); /* returns 0x3412 */
UTIL_htonl(0x12345678); /* returns 0x78563412 */

Я понятия не имею, как написать их в Delphi ...

Надеюсь, они уже написаны, и библиотека, используемая Delphi, имеет их с тем или иным именем.Проверьте свою документацию.


Редактировать

nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 ) | ( pBuffer[ 1 ] & 0x00FF );

в этой строке

pBuffer[0] - первый элемент массива pBuffer
pBuffer[0] << 8 сдвигает это значение на 8 бит влево (0x12 становится 0x1200)
(...) & 0xFF00 является избыточным: сбрасывает самые правые 8 бит

В pBuffer[1] & 0x00FF сохраняются только самые правые 8 бит (поэтому 0x1234становится 0x0034)

Другая операция | является побитовой или

( ... & 0xFF00) | ( ... & 0xFF00) - самые левые 8 битов первой части и самые правые 8 битов второй части.


Редактировать: hto * / * toh naming

Функции htonl, htons, ntohl, ntohs в C используются для преобразования значений между хостом и сетевым порядком байтов.

Порядок следования байтов не обязательно отличается (порядок байтов в сети имеет порядок с прямым порядком байтов), поэтому перед выполнением перестановок первая часть функций должна проверять, является ли порядок байтов в узле хоста прямым или младшим... или проверка была сделана ранее в программе, которая использует опубликованные вами функции.

3 голосов
/ 14 ноября 2010

Вам не нужно переводить их, просто включите WinSock, в нем есть все четыре!

2 голосов
/ 14 ноября 2010

Кажется, это просто обмен байтов, который вы можете реализовать очень просто:

function Swap32(const Value: DWORD): DWORD; assembler;
asm
  bswap eax;
end;

function Swap16(const Value: WORD): WORD; assembler;
asm
  xchg al, ah;
end;
0 голосов
/ 14 ноября 2010

довольно неясное побитовое выражение

nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
 | ( pBuffer[ 1 ] & 0x00FF );

подразумевает, что:

var 
  pBuffer: PByteArray; 
  nResult: Word;

так что структурированная ясность Паскаля будет выглядеть так:быть довольно очевидным здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...