type
TArgPtr =record
private
FArgPtr: PByte;classfunction Align(Ptr: Pointer; Align: Integer): Pointer; static;
public
constructor Create(LastArg: Pointer; Size: Integer); // Read bytes, signed words etc. using Int32 // Make an unsigned version if necessary. function ReadInt32: Integer; // Exact floating-point semantics depend on C compiler. // Delphi compiler passes Extended as 10-byte float; most C // compilers pass all floating-point values as 8-byte floats. function ReadDouble: Double; function ReadExtended: Extended; function ReadPChar: PChar; procedure ReadArg(var Arg; Size: Integer); end;
constructor TArgPtr.Create(LastArg: Pointer; Size: Integer); begin
FArgPtr := LastArg;// 32-bit x86 stack is generally 4-byte aligned
FArgPtr := Align(FArgPtr + Size,4); end; classfunction TArgPtr.Align(Ptr: Pointer; Align: Integer): Pointer; begin
Integer(Result):=(Integer(Ptr)+ Align -1)and not(Align -1); end; function TArgPtr.ReadInt32: Integer; begin
ReadArg(Result, SizeOf(Integer)); end; function TArgPtr.ReadDouble: Double; begin
ReadArg(Result, SizeOf(Double)); end; function TArgPtr.ReadExtended: Extended; begin
ReadArg(Result, SizeOf(Extended)); end; function TArgPtr.ReadPChar: PChar; begin
ReadArg(Result, SizeOf(PChar)); end; procedure TArgPtr.ReadArg(var Arg; Size: Integer); begin
Move(FArgPtr^, Arg, Size);
FArgPtr := Align(FArgPtr + Size,4); end; procedure Dump(const types:string); cdecl; var
ap: TArgPtr;
cp: PChar; begin
cp := PChar(types);
ap := TArgPtr.Create(@types, SizeOf(string)); while True do begin case cp^ of #0:begin
Writeln;
Exit; end; 'i': Write(ap.ReadInt32,' '); 'd': Write(ap.ReadDouble,' '); 'e': Write(ap.ReadExtended,' '); 's': Write(ap.ReadPChar,' '); else
请发表评论