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

时间:2016-07-14 10:12:24

标签: delphi delphi-7 delphi-5

我试图将DDetours lib移植到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

编译错误:

  

[错误] InstDecode.pas(882):运算符不适用于此操作数   型

PInst^.VirtualAddr, PInst^.NextInst, PInst^.Addr都声明为PBytePByte = ^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;

2 个答案:

答案 0 :(得分:6)

在较新的Delphi版本中,PByte可用于指针算术。在此之前,唯一可以执行此操作的类型是PCharPAnsiCharPWideChar)。在Delphi 5中,PCharPAnsiChar

更新

现在我知道记录的结构并知道你想要实现的目标,我想你应该做以下几点。

您可以将PBytes中的所有TInstruction更改为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

答案 1 :(得分:0)

在Delphi 5下,尝试:

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位可执行文件下工作。