如何处理 D5/D7 中的 PByte 指针操作(运算符不适用于此操作数类型)

How to handle PByte pointer operations in D5/D7 (Operator not applicable to this operand type)

我正在尝试将 DDetours 库移植到 Delphi 5/7。不会编译的行具有这种模式:

procedure Decode_J(PInst: PInstruction; Size: Byte);
var
  Value: Int64;
  VA: PByte;
begin
  ...
  VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr) // <- compiler error

编译器错误:

[Error] InstDecode.pas(882): Operator not applicable to this operand type

PInst^.VirtualAddr, PInst^.NextInst, PInst^.Addr 都声明为 PByte (PByte = ^Byte)

我该怎么做才能解决这个问题?


编辑:

PInstruction 定义为:

  TInstruction = record
    Archi: Byte; { CPUX32 or CPUX64 ! }
    AddrMode: Byte; { Address Mode }
    Addr: PByte;
    VirtualAddr: PByte;
    NextInst: PByte; { Pointer to the Next Instruction }
    OpCode: Byte; { OpCode Value }
    OpType: Byte;
    OpKind: Byte;
    OpTable: Byte; { tbOneByte,tbTwoByte,... }
    OperandFlags: Byte;
    Prefixes: Word; { Sets of Prf_xxx }
    ModRm: TModRM;
    Sib: TSib;
    Disp: TDisplacement;
    Imm: TImmediat; { Primary Immediat }
    ImmEx: TImmediat; { Secondary Immediat if used ! }
    Branch: TBranch; { JMP & CALL }
    SegReg: Byte; { Segment Register }
    Rex: TRex;
    Vex: TVex;
    LID: TInternalData; { Internal Data }
    Errors: Byte;
    InstSize: Byte;
    Options: Byte;
    UserTag: UInt64;
  end;

  PInstruction = ^TInstruction;

下Delphi5,试试:

procedure Decode_J(PInst: PInstruction; Size: Byte);
var
  Value: Int64;
  VA: PByte;
begin
  ...
  VA := PByte(integer(PInst^.VirtualAddr) + (integer(PInst^.NextInst) - integer(PInst^.Addr))); 

使用integer() 类型转换可能会解决指针运算问题。但它只能在 32 位可执行文件下运行。

在较新的 Delphi 版本中,PByte 可用于指针运算。在此之前,唯一可以做到这一点的类型是 PCharPAnsiCharPWideChar)。在Delphi5中,PChar是一个PAnsiChar.

更新

现在我知道了记录的结构,也知道你想要实现什么,我想你大概应该做下面的事情。

您可以将 TInstruction 中的所有 PBytes 更改为 PAnsiChar(或 PChar,如果您只关心 D5),以及所有 PBytes在每个例程中。然后你得到:

PInstruction = ^TInstruction;
TInstruction = record
  Archi: Byte; { CPUX32 or CPUX64 ! }
  AddrMode: Byte; { Address Mode }
  Addr: PAnsiChar;
  VirtualAddr: PAnsiChar;
  NextInst: PAnsiChar; { Pointer to the Next Instruction }
  ...
end;

...

procedure Decode_J(PInst: PInstruction; Size: Byte);
var
  Value: Int64;
  VA: PAnsiChar;
begin
  ...
  VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr);
  ...

但请注意,如果您想使用这些 PAnsiChars 读取或写入一个字节,则必须将它们转换为 PByte