2010-11-13 8 views
4

Je convertis du code C en Delphi. Quelqu'un peut-il m'expliquer s'il vous plaît ce que cette ligne signifie?Que signifie cette ligne de code C?

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

Voici le reste du code pour le contexte:

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)); 
} 

Merci à l'avance Bojan

+3

Qu'avez-vous essayé jusqu'à présent? Sur quoi êtes-vous coincé? Nous aimons aider les gens qui s'aident eux-mêmes, pas seulement faire leur travail pour eux. – Oded

+0

Ok. Pour reformuler la question. Quelqu'un peut-il m'expliquer la signification de cette ligne nResult = ((pBuffer [0] << 8) & 0xFF00) | (pBuffer [1] & 0x00FF); –

+1

Je ligne épaisse citée est auto-expliquant. il obtient 8 bits d'un élément tampon, puis 8 bits d'un autre, puis les concatène togeter. – Vovanium

Répondre

4

Apparemment (tous les définit en majuscules rendent difficile la lecture), les fonctions sont permutant les ordre interne des octets des valeurs qui occupent 2 ou 4 octets. Par exemple:

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

Je ne sais pas comment les écrire dans Delphi ...

Espérons qu'ils sont déjà écrits et la bibliothèque Delphi utilise les a avec un nom ou une autre. Vérifiez votre documentation.


Modifier

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

dans cette ligne

pBuffer[0] est le premier élément du tableau pBuffer
pBuffer[0] << 8 se déplace que la valeur de 8 bits vers la gauche (0x12 devient 0x1200)
(...) & 0xFF00 est redondant: réinitialise les 8 bits les plus à droite

Dans pBuffer[1] & 0x00FF seuls les 8 bits les plus à droite sont conservés (donc 0x1234 devient 0x0034)

L'autre opération | est une opération de bits ou

(... & 0xFF00) | (... & 0xFF00) est le plus à gauche de 8 bits de la première partie et la plus à droite 8 bits de La seconde partie.


Edit: HTO */* toh dénomination

Les fonctions htonl, htons, ntohl, ntohs en C sont utilisées pour convertir des valeurs entre l'hôte et l'ordre des octets du réseau. L'ordre des octets n'est pas nécessairement différent (l'ordre des octets du réseau est big-endian), donc la première partie des fonctions doit vérifier si l'ordre des octets de l'hôte est petit ou gros-endian avant de faire les swaps ... ou la vérification a été effectuée précédemment dans le programme qui utilise les fonctions que vous avez affichées.

+0

Merci pour vos réponses. Dans le débogage du code c et du code delphi j'ai fait des résultats similaires: par exemple nIPOffset = UTIL_ntohs (64) en utilisant le débogueur VC montre la valeur 16384. Même résultat que j'ai dans delphi en utilisant ntohs (64). Mais printf ("nIPOffset% d \ n", nIPOffset); affiche 20. –

+0

nIPOffset = UTIL_ntohs (ip-> ip_off); // débogueur affiche 16384 même résultat delphi printf ("nIPOffset% d \ n", nIPOffset); // Le résultat à l'écran est 20. Cela est compensé lorsque je dois lire de nouvelles données. La longueur des données est d'environ 40 –

+0

L'utilisation de "% d" dans 'printf' indique à printf d'utiliser un int (généralement 4 octets) à partir des arguments. Mais nIPOffset semble être long ou long (8 octets). Si mes hypothèses sont correctes, 'printf' ignorera 4 octets de la valeur. – pmg

3

Vous ne devez pas les traduire, il suffit d'inclure WinSock, il a tous les quatre!

2

Il semble être juste un échange d'octets que vous pouvez mettre en œuvre très simplement:

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

function Swap16(const Value: WORD): WORD; assembler; 
asm 
    xchg al, ah; 
end; 
+0

Il y a une fausse note * rétrocompatibilité seulement * procédure intrinsèque 'Swap()' pour byteswap 16 bits (inline, sauvegarde sur CALL/RET) Aussi, qu'est-ce que le spécificateur const? Voulez-vous vraiment byteswap ** adresse ** du paramètre? –

+0

Non, je ne veux pas échanger l'adresse, la const est juste parce que nous n'avons pas besoin de faire une copie – Remko

0

plutôt obscure expression bitwise

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

implique que:

var 
    pBuffer: PByteArray; 
    nResult: Word; 

donc, La clarté structurée de Pascal ressemblerait à:

WordRec(nResult).Hi := pBuffer^[0]; 
WordRec(nResult).Lo := pBuffer^[1]; 

byteswap même implicite est ici étant assez évident