Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Funcion ORD en Delphi 7 devuelve valor diferente que en Delphi 11 Alexandria (https://www.clubdelphi.com/foros/showthread.php?t=96704)

Matorral 20-05-2024 12:31:07

Funcion ORD en Delphi 7 devuelve valor diferente que en Delphi 11 Alexandria
 
Buenos días¡¡

Estoy cambiando un viejo programa desarrollado en Delphi7 a Delphi 11 Alexandria.
Tengo un problema con una función "Codifica()", que en Delphi7 me devuelve un valor, y en Delphi 11 me devuelve otro diferente.

Delphi 7:
Código Delphi [-]
function Codifica(v: string): integer;
var wClave1: string;
    i,j: longint;
begin
   j:=0;
   wclave1 :=v;
   for i:=1 to Length(wClave1) do
      j:=j*255+ord(wClave1[i]);

   j:=j*7;
   Result:=j;
end;

Delphi 11:
Código Delphi [-]
function Codifica(v: string): int64;
var wClave1: string;
    i,  j:int64;
begin
   j:=0;
   wclave1 :=v;
   for i:=1 to Length(wClave1) do
      j:=j*255+ord(wClave1[i]);
   j:=j*7;
   Result:=j;
end;

Pasando como parámetro ‘1111’ en Delphi4 me devuelve ‘1414835712’ y en Delphi 11 me devuelve ‘5709803008’.

El tipo integer (delphi7) lo cambié por int64(delphi11) porque me daba un error de ejecución "integer overflow".

Supongo que tendrá que ver con que en delphi 11 la funcion system.ord devuelve un valor tipo byte y en Delphi 7 de tipo integer, pero no se cómo solucionarlo.

Alguien podría darme una pista de que tendría que hacer para que el valor devuelto en Delphi11 fuese igual al devuelto por la funcion de Delphi7?

Gracias de antemano¡¡

pgranados 20-05-2024 17:42:36

Hola, acabo de hacer la prueba en Delphi 10.4 y obtengo el mismo resultado con ambas funciones: 1414835712

Te recomendaria poner un stop en Delphi 11 para ver en donde esta cambiando el valor.

pgranados 20-05-2024 17:43:36

Aunque otra alternativa seria que hagas una DLL en Delphi 7 y la consumas desde Delphi 11

Matorral 28-05-2024 12:28:33

Buenos dias¡¡

Siento haber tardado tanto en responder, no pude hacerlo antes.

Cita:

Empezado por pgranados (Mensaje 555706)
Hola, acabo de hacer la prueba en Delphi 10.4 y obtengo el mismo resultado con ambas funciones: 1414835712

Te recomendaria poner un stop en Delphi 11 para ver en donde esta cambiando el valor.

Gracias por responder pgranados.


El valor esta cambiando en esta línea, al introducir el cuarto dígito ('1111').

Código Delphi [-]
     j:=j*7;


Y creo que el problema es que en Delphi 7 utilizo variables tipo integer y en Delphi 11 variables int64 (en Delphi 11 no puedo declarar la variable "j" como integer o como LongInt porque salta un error al introducir el cuarto dígito (el cuarto '1') :

"Integer overflow".


Cita:

Empezado por pgranados (Mensaje 555706)
Aunque otra alternativa seria que hagas una DLL en Delphi 7 y la consumas desde Delphi 11

También probé a hacer la dll en Delphi 7 y consumirla desde Delphi 11 y dan valores diferentes.


La "putada" es que el valor de la función Codifica() lo guardo en el registro de cada usuario. Al entrar en la aplicación pido el pin, lo codifico y hago una búsqueda del valor devuelto por Codifica() para identificar al usuario.
Al ejecutar la aplicación compilada con Delphi 11 no localiza el pin codificado.:(

En fin, seguiré buscando una solución a esto porque necesito mantener la Codificación antigua del pin (Delphi 7) en la aplicación actualizada a Delphi 11.

Gracias pgranados¡¡

egostar 28-05-2024 16:14:11

Hola

Esto es lo que hace Delphi 7 conforme vas realizando tus operaciones aritméticas.

1 - 49
1 - 12544
1 - 3198769
1 - 815686144

815686144 * 7 = 1414835712

Pero en realidad si se multiplica esa cantidad por 7 el resultado debería ser 5,709,803,008 como te lo genera Delphi 11

Me parece que Delphi 7 no está evaluando el overflow del entero y lo está truncando en lugar de enviar la excepción, algo que yo no había visto hasta ahora. :confused:

Ahora, eso trae muchas inconsistencias en tu aplicación (desde mi punto de vista).

Saludos

Matorral 28-05-2024 22:37:09

Gracias Egostar.

Cita:

Empezado por egostar (Mensaje 555774)
Ahora, eso trae muchas inconsistencias en tu aplicación (desde mi punto de vista).

Pues si, lo que me preocupa ahora mismo es como actualizar las versiones de los clientes para mantenerles el pin de los usuarios.

Muchas gracias¡¡

egostar 29-05-2024 05:29:18

Cita:

Empezado por Matorral (Mensaje 555788)
Gracias Egostar.



Pues si, lo que me preocupa ahora mismo es como actualizar las versiones de los clientes para mantenerles el pin de los usuarios.

Muchas gracias¡¡

Hola

En este caso lo que yo intentaría es crear una DLL con Delphi 7 que haga esa operación y regrese el dato esperado.

Saludos

Matorral 29-05-2024 10:02:42

Hola¡¡

Cita:

Empezado por egostar (Mensaje 555790)
Hola

En este caso lo que yo intentaría es crear una DLL con Delphi 7 que haga esa operación y regrese el dato esperado.

Saludos

Lo había intentado por medio de una dll cuando me lo dijo pgranados y el resultado obtenido con Delphi 11 era diferente al esperado (1414835712).

Ahora puse un showmessage en la dll para ver la diferencia digito a digito y ya no entiendo nada. Cuando ejecuto la funcion los dígitos pares (wClave1[i]) no tienen valor :confused:

Os paso la dll hecha en Delphi7...

Código Delphi [-]
library dllCodifica;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes,
  Dialogs;

{$R *.res}

function Codifica (v : string): int64; stdcall;
var wClave1: string;
    i:integer;
    j: int64;
begin

   j:=0;
   wclave1 := v;

   for i:=1 to Length(wClave1) do  begin
      j:=j*255+ord(wClave1[i]);

        showmessage(' Después de operacion '+chr(10)+chr(13)+
                 'i = '+inttostr(i)+chr(10)+chr(13)+
                 'j = '+inttostr(j)+chr(10)+chr(13)+
                 'wClave1[i] = '+wClave1[i]+chr(10)+chr(13)+
                 'ord(wClave1[i]) = '+inttostr(ord(wClave1[i]))+chr(10)+chr(13)+
                 'j:=j*255+ord(wClave1[i]) = '+inttostr(j*255+ord(wClave1[i]))+chr(10)+chr(13)+
                 'j:=j*7 = '+inttostr(j*7));
   end;

   j:=j*7;

   Result:=j;

end;

exports Codifica;

begin
end.

y este es la rutina en Delphi 12 que consume la dll...

Código Delphi [-]
unit CODIFICA;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

var Lib : THandle;
    dllCodifica: function(v:String):int64; stdcall;


implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  label1.caption:=IntToStr(dllCodifica(edit1.Text));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

    Lib:=LoadLibrary('dllCodifica.dll');
    dllCodifica := GetProcAddress(Lib,'Codifica');

end;

end.

Desde Delphi 12, al introducir '1111' en el edit y luego al hacer click en el boton, muestra el resultado digito a digito, y en los digitos pares aparece un valor nulo en wClave1[i].

Desde Delphi 7 da el valor esperado.

No entiendo nada, se me escapa.
:confused::confused::confused:

Gracias¡¡

egostar 29-05-2024 19:45:07

Cita:

Empezado por Matorral (Mensaje 555798)
Hola¡¡
.....
Desde Delphi 12, al introducir '1111' en el edit y luego al hacer click en el boton, muestra el resultado digito a digito, y en los digitos pares aparece un valor nulo en wClave1[i].

Desde Delphi 7 da el valor esperado.

No entiendo nada, se me escapa.
:confused::confused::confused:

Gracias¡¡

Bueno, es que el detalle es que no estás considerando Unicode.

Crea la DLL en Delphi 7 así


Código Delphi [-]
library DLLCodifica;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.res}

function Codifica(v: WideString): integer; stdcall;
var
  wClave1: string;
  i,j: longint;
begin
  j := 0;
  wclave1 := v;
  for i := 1 to Length(wClave1) do
  j := j * 255 + ord(wClave1[i]);
  j := j * 7;
  Result := j;
end;

exports
  Codifica;
  
begin
end.

Y con Delphi 11 consumela así


Código Delphi [-]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  dllCodifica = function(v: WideString): integer; stdcall;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Handle: THandle;
  procInt: dllCodifica;
  Regreso: integer;
begin
  Regreso := 0;
  Handle := LoadLibrary( PChar(ExtractFilePath(ParamStr(0)) + 'DLLCodifica.dll') );
  if Handle <> 0 then
  begin
    @procInt := GetProcAddress(Handle, PChar('Codifica'));
    if @procInt <> nil then
    try
      Regreso := procInt('1111');
      ShowMessage(Regreso.ToString);
    except
      on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
    end;
  end;
  FreeLibrary(Handle);
end;

end.


Matorral 29-05-2024 21:37:18

Muchas gracias egostar¡¡¡¡

Que crack¡¡

Va perfecto.

Millón de gracias¡¡ (y una cervecita a mi salud¡¡)


La franja horaria es GMT +2. Ahora son las 15:41:17.

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