Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ayuda conversión C++ a Delphi (https://www.clubdelphi.com/foros/showthread.php?t=84724)

DarkDudae 28-11-2013 11:58:05

Ayuda conversión C++ a Delphi
 
Buenos días:

Tengo mi C++ un poco oxidado (vamos, como que no lo toco desde el 2000). El caso es que tengo que portar un par de funciones de C a Delphi para unos cálculos de CRC no estándares.

Los códigos en cuestión son los siguientes:

Código:

unsigned char crc8 (unsigned char *ptr, unsigned int length)
{
unsigned char crc; unsigned int i,n; unsigned int datum; unsigned char merker;
crc = 0;
for (i=0; i < (length); i++) {
datum = *ptr++;
crc ^= datum;
for (n=0; n<8; n++) {
if (crc & 1) merker = 1; else merker = 0;
crc >>= 1;
if (merker) crc ^= 0x92; }
}
return (crc);
}


Código:

unsigned int crc16 (unsigned char *ptr, unsigned int length)
{
unsigned int crc, datum; unsigned int i,n;
unsigned char highbyte, lowbyte; unsigned char merker;
crc = 0;
for (i=0; i < (length/2); i++) {
highbyte = *ptr++; lowbyte = *ptr++; datum = highbyte; datum <<= 8; datum |= lowbyte; crc ^= datum;
for (n=0; n<16; n++) {
merker = (crc & 1);
crc >>= 1;
if (merker) crc ^= 0x8408;
} }
return (crc);
}

La función recibirá un array de bytes, así pues, la he portado a delphi de la siguiente forma:

Código Delphi [-]
function CRC8Portada(ptr:array of Byte; longitud: Cardinal): Byte;
var
crc:Byte;
i,n:Cardinal;
datum:Cardinal;
merker:Byte;
begin
  crc:=0;
  for i:=0 to longitud-1 do
    begin
      datum:=ptr[i+1];
      crc:=crc xor datum;
      for n:=0 to 7 do
        begin
          if (crc=1) then merker:=1
            else merker:=0;
          crc:=crc shr 1;
          if (merker=1) then crc:=crc xor $92;
        end;
    end;
    result:=crc;

end;

Código Delphi [-]
function CRC16Portada(ptr:array of Byte; longitud: Cardinal): Byte;
var
crc:Byte;
i,n:Cardinal;
datum:Cardinal;
merker, highbyte, lowbyte:Byte;
begin
  crc:=0;
  for i:=0 to ((longitud div 2)-1) do
    begin
      highbyte:=ptr[i];
      lowbyte:=ptr[i+1];
      datum:=highbyte;
      datum:=datum shl 8;
      datum:=datum OR lowbyte;
      crc:=crc xor datum;
      for n:=0 to 15 do
        begin
          if (crc=1) then merker:=1
            else merker:=0;
          crc:=crc shr 1;
          if (merker=1) then crc:=crc xor $0408;
        end;
    end;
    Result:=crc;
end;

Lo que probablemente está mal de la función es el tema de los punteros de C, pero lo cierto es que no recuerdo cómo portarlos:

Es decir:

datum = *ptr++; (¿Tal vez con Addrs o Pointer?)

Tampoco sé cómo portar sentencias como:
merker = (crc & 1);
o
datum |= lowbyte

Cualquier ayuda será bienvenida...

ecfisa 28-11-2013 18:30:00

Hola DarkDudae.

Desconozco la funcionalidad del código, pero enviándole los mismos valores como argumentos, de este modo obtengo resultados idénticos en C++ Builder y Delphi:
Código Delphi [-]
function crc8(ptr: array of Byte; length: Word): Byte;
var
  i,n,datum : Word;
  merker: Byte;
begin
  Result:= 0;
  for i:= Low(ptr) to High(ptr) do
  begin
    datum := ptr[i];
    Result:= Result xor datum;
    for n:= 0 to 7 do
    begin
      merker:= Integer(Boolean(Result and 1));
      Result:= Result shr 1;
      if Boolean(merker) then
        Result:= Result xor $92;
    end;
  end;
end;

Código Delphi [-]
function crc16(ptr: array of Byte; length: Word): Word;
var
  i, n, j, datum : Word;
  highbyte, lowbyte, merker: Byte;
begin
  Result:= 0;
  j:= 0;
  for i:= 0 to (length shr 1)-1 do
  begin
    highbyte:= ptr[j];
    Inc(j, SizeOf(Byte));
    lowbyte := ptr[j];
    Inc(j, SizeOf(Byte));
    datum   := highbyte;
    datum   := datum shl 8;
    datum   := datum or lowbyte;
    Result  := Result xor datum;
    for n:= 0 to 15 do
    begin
      merker:= Result and 1;
      Result:= Result shr 1;
      if Boolean(merker) then
        Result:= Result xor $8408;
    end;
  end;
end;
Proba las funciones y me comentas.

Saludos :)

Edito: Donde dije "Desconozco la funcionalidad" quise decir que desconozco si el código original funciona, disculpas por la redacción :o

nlsgarcia 28-11-2013 18:38:19

DarkDudae,

Cita:

Empezado por DarkDudae
...tengo que portar un par de funciones de C a Delphi para unos cálculos de CRC no estándares...

Revisa este link:
Espero sea útil :)

Nelson.

DarkDudae 28-11-2013 19:12:48

Cita:

Empezado por ecfisa (Mensaje 470182)
Hola DarkDudae.

Desconozco la funcionalidad del código, pero enviándole los mismos valores como argumentos, de este modo obtengo resultados idénticos en C++ Builder y Delphi:

.
.
.

Proba las funciones y me comentas.

Saludos :)

Edito: Donde dije "Desconozco la funcionalidad" quise decir que desconozco si el código original funciona, disculpas por la redacción :o

Funciona perfectamente. Mil gracias ecfisa.
Estaba a punto de armarme una DLL en C++ con las funciones expuestas para invocarlas desde Delphi como penúltimo recurso.

@nlsgarcia:

Gracias igualmente por responder. Lo cierto es que ya había visto todas esas funciones y he llegado a implementarlas en mi código. El problema es que las funciones no usan los polinomios "estándar".

En concreto los polinomios son los siguientes:

CRC-16 = X^14+X^12+X^5+1
CRC-8 = X^8+X^6+X^3+1

El caso es que pese a crearme mis propias funciones de CRC con base de esos algoritmos, me arrojaban valores distintos a los de las funciones originales de C++. (Incluso probé en varias calculadoras online que permiten la introducción del polinomio para asegurarme). Así pues, he de asumir que la documentación que me pasaron es incorrecta o está incompleta.

Menos mal que ecfisa me ha sacado de mi pozo de ignorancia en C++.

Nuevamente, gracias a ambos


La franja horaria es GMT +2. Ahora son las 09:32:08.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi