Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Error paso de parametro mediante direccion de memoria en D7 (https://www.clubdelphi.com/foros/showthread.php?t=97158)

CrazySoft 08-01-2025 17:06:16

Error paso de parametro mediante direccion de memoria en D7
 
Buen día, una favor como puedo modificar este código para usar en Delphi 7, da el siguiente error "Operator not applicable to this operand type" al asignar un valor a (pB + 1)^=1; el Delphi 10XE compila correctamente



Gracias por su colaboración



Código Delphi [-]
function THidRlyForm.SendCmd(Relay, Mode: Byte): String; 
var   pB,pB1,pB2,pB0,pB8: pByte;   
Dev:  TJvHidDevice;   
Status: Boolean; 
begin   
Dev := TJvHidDevice(lbBoards.Items.Objects[lbBoards.ItemIndex]);  
 try
     pB := AllocMem(10);
       pB^      := 0;    
 (pB + 1)^ := Mode;  // Error Operator not applicable to this operand type     
(pB + 2)^ := Relay;
      Status := Dev.SetFeature(pB^, 9);
      if Status then       Result := Format('%2.2x %2.2x %2.2x', [(pB + 0)^, (pB + 1)^, (pB + 2)^])
     else 
      Result := 'Command not sent';
      Status := Dev.GetFeature(Pb^, 9);
     if Status then       Result := Format('%s - %2.2x', [Result, (pB + 8)^]);
   finally
     FreeMem(pB);
   end;
 end;

Casimiro Notevi 08-01-2025 18:39:03

El error ocurre porque en las versiones más recientes de Delphi, los punteros ya no se pueden manipular aritméticamente de forma directa, como en versiones más antiguas. Esto está relacionado con los cambios en la administración de punteros y tipos de datos en el compilador.
Para resolver el problema, necesitas convertir el puntero a un tipo entero adecuado para realizar la aritmética, y luego volver a convertirlo a un puntero. Aquí tienes una forma de hacerlo:


Código Delphi [-]
function THidRlyForm.SendCmd(Relay, Mode: Byte): String;
var
  pB: PByte;
  Dev: TJvHidDevice;
  Status: Boolean;
begin
  Dev := TJvHidDevice(lbBoards.Items.Objects[lbBoards.ItemIndex]);
  try
    pB := AllocMem(10);
    try
      pB^ := 0; // Primer byte
      (PByte(NativeUInt(pB) + 1))^ := Mode;  // Segundo byte
      (PByte(NativeUInt(pB) + 2))^ := Relay; // Tercer byte

      Status := Dev.SetFeature(pB^, 9);
      if Status then
        Result := Format('%2.2x %2.2x %2.2x', [pB^, (PByte(NativeUInt(pB) + 1))^, (PByte(NativeUInt(pB) + 2))^])
      else
        Result := 'Command not sent';

      Status := Dev.GetFeature(pB^, 9);
      if Status then
        Result := Format('%s - %2.2x', [Result, (PByte(NativeUInt(pB) + 8))^]);
    finally
      FreeMem(pB);
    end;
  end;
end;


Cita:

Cambios explicados:
  1. NativeUInt: Se usa para convertir el puntero pB en un entero sin signo que permite realizar la aritmética de punteros de manera segura.
  2. PByte: Se utiliza para volver a convertir el entero a un puntero de tipo PByte, de forma que se pueda acceder al valor de la dirección de memoria correcta.
  3. Manejo de memoria: La asignación y liberación de memoria (AllocMem y FreeMem) permanece igual.
Detalles adicionales:
  • La función NativeUInt es compatible con Delphi moderno y asegura que la manipulación de punteros sea válida tanto en plataformas de 32 bits como de 64 bits.
  • Asegúrate de que Dev.SetFeature y Dev.GetFeature manejen correctamente los datos, especialmente si dependen de buffers de longitud fija.

Lo he copiado del chatgpt.

CrazySoft 08-01-2025 19:18:10

Muchas gracias Casimiro, funciono bien, no sabia eso lo de los punteros

Casimiro Notevi 08-01-2025 19:24:31

Yo tampoco lo sabía, todavía sigo con versiones obsoletas de delphi.


La franja horaria es GMT +2. Ahora son las 23:26:45.

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