Si vous êtes vraiment désespéré de patcher revenir au comportement précédent, vous pouvez utiliser quelque chose comme ceci:
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);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
OldProtect: DWORD;
begin
if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
Move(NewCode, Address^, Size);
FlushInstructionCache(GetCurrentProcess, Address, Size);
VirtualProtect(Address, Size, OldProtect, @OldProtect);
end;
end;
type
PInstruction = ^TInstruction;
TInstruction = packed record
Opcode: Byte;
Offset: Integer;
end;
procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
NewCode: TInstruction;
begin
NewCode.Opcode := $E9;//jump relative
NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp;
const
FMSecsPerDay: Single = MSecsPerDay;
IMSecsPerDay: Integer = MSecsPerDay;
var
LTemp, LTemp2: Int64;
begin
LTemp := Round(DateTime * FMSecsPerDay);
LTemp2 := (LTemp div IMSecsPerDay);
Result.Date := DateDelta + LTemp2;
Result.Time := Abs(LTemp) mod IMSecsPerDay;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(FormatDateTime('dd/mm/yyyy', -693594));
end;
initialization
RedirectProcedure(@System.SysUtils.DateTimeToTimeStamp, @DateTimeToTimeStamp);
end.
Cela fonctionne pour 32 bit code. Il fonctionnera également pour le code 64 bits à condition que les anciennes et les nouvelles fonctions résident dans le même module exécutable. Sinon, la distance de saut peut dépasser la plage d'un entier de 32 bits. Cela ne fonctionnera pas non plus si votre RTL réside dans un package d'exécution. Ces deux limitations peuvent être facilement corrigées.
Ce code permet de rediriger tous les appels vers SysUtils.DateTimeToTimeStamp
vers la version implémentée dans cet appareil. Le code dans cette unité est juste la version PUREPASCAL
de la source XE2.
La seule autre approche qui répond aux besoins décrits dans vos commentaires est de modifier et recompiler l'unité SysUtils elle-même, mais j'évite personnellement ce genre de solution.
Je peux me tromper, mais ne veut pas dire « passer quoi que ce soit moins -693594 »? aussi, cela fonctionne dans XE, que diriez-vous de copier-coller la fonction d2006 dans le projet "utils" et ajoutez toujours cela comme dernière unité dans la clause "uses", de cette manière le compilateur utilisera CELA au lieu de celui par défaut. – ComputerSaysNo
Ecrivez votre propre fonction qui enveloppe la fonction rtl et détecte la valeur sentinelle dans cette enveloppe –
@David Heffernan: +1! Pas de code cuillère – menjaraz