Jump to content
sp0987

Changes in System.sysutils.pas were not reflecting in other unit in Delphi 11

Recommended Posts

Having read through this entire thread, I can only repeat what others already said: Changing the interface part of SysUtils requires recompiling nearly all other RTL and VCL units. That was already the case with Delphi 7.

 

I also agree that this is most likely not the best solution to your actual problem.

 

You said you needed a global variable in the interface section of SysUtils that multiple functions in that unit access. Which functions are you talking about and what is the purpose of this change? If you don't tell us, we can't suggest alternative solutions.

  • Like 3

Share this post


Link to post
16 hours ago, Anders Melander said:

I'm guessing the compiler options used to compile your sysutils copy might also have importance. Maybe someone else knows that.

The source\rtl folder contains projects to build the RTL for different platforms.

Share this post


Link to post
Posted (edited)

Edit: never mind, my comment was wrong in this case.

Edited by Brandon Staggs

Share this post


Link to post
On 5/1/2024 at 12:40 PM, Dave Nottage said:

we have SysUtils added to the uses clause of (almost) every unit in the project,

If this is to us, i have tested the same with sample application with only one unit in it. 

Share this post


Link to post
On 4/30/2024 at 8:46 PM, Anders Melander said:

Now you just need to add the path of all the VCL/RTL units that use that unit so you can avoid "F2051 Unit XXX was compiled with a different version of YYY"

As per the suggestion , it looks like this ,and the chain goes till all the folders are included. Was i right?

image.thumb.png.4fb86284388aa6e0751558c0b88a5f68.png

Share this post


Link to post

Nobody really cares that much. It's a gruesome way to go. I'd solve the problem properly but you don't want to tell us what the problem is. 

  • Like 6

Share this post


Link to post
1 hour ago, David Heffernan said:

Nobody really cares that much. It's a gruesome way to go. I'd solve the problem properly but you don't want to tell us what the problem is. 

We need to modify all sysutils date time functions

Share this post


Link to post
19 minutes ago, sp0987 said:

We need to modify all sysutils date time functions

What are you trying to achieve with this?

Share this post


Link to post
1 hour ago, sp0987 said:

We need to modify all sysutils date time functions

A more straightforward way to do this is to just make your own date/time library, not modify the one in the RTL.

Share this post


Link to post
1 hour ago, sp0987 said:

We need to modify all sysutils date time functions

Are you aware of the overloaded functions that take an additional TFormatSettings parameter?

Share this post


Link to post
14 hours ago, sp0987 said:

We need to modify all sysutils date time functions

Why though? 

Share this post


Link to post

In Delphi 7 we easily intercepted/modified result of all DateTime core functions as Now, Date, Time etc. to use our DateTime (not the real OS DateTime) for testing purposes without the need to change the machine's OS time. D7 easily allowed us to do that introducing an optional event. Here is a small example how we successfully handled it in D7:

 

type
  TGetTbtTime = procedure(var st: TSystemTime) of object;
var
  gGetTbtTime: TGetTbtTime;

 

procedure tbtLocalTime(var st: TSystemTime);
begin
  if Assigned(gGetTbtTime) then
    gGetTbtTime(st) // HERE WE PROVIDE BACK OUR OWN DATETIME
  else
    Window.GetLocalTime(st);
end;

 

// NATIVE DELPHI FUNCTION

function Date: TDateTime;
var
  SystemTime: TSystemTime;
begin
  tbtLocalTime(SystemTime);
  with SystemTime do
    Result := EncodeDate(wYear, wMonth, wDay);
end;
 

D11 is giving us a hard time to do the same.

 

Share this post


Link to post
Posted (edited)
20 hours ago, dummzeuch said:

Are you aware of the overloaded functions that take an additional TFormatSettings parameter?

related to datetime or datetime conversions?

 

Edited by sp0987

Share this post


Link to post
15 minutes ago, sp0987 said:

to use our DateTime (not the real OS DateTime) for testing purposes without the need to change the machine's OS time.

This little utility always worked pretty well for me: RunAsDate

  • Like 2

Share this post


Link to post
43 minutes ago, Uwe Raabe said:

This little utility always worked pretty well for me: RunAsDate

The utility was a good suggestion. Thanks for that.

But, in our case we would like to handle it in our code as we sync the changes with DB and other's. 

Share this post


Link to post
1 hour ago, sp0987 said:

In Delphi 7 we easily intercepted/modified result of all DateTime core functions as Now, Date, Time etc. to use our DateTime (not the real OS DateTime) for testing purposes without the need to change the machine's OS time.

Rather than editing SysUtils (and having to keep your changes up to date every time you upgrade Delphi), Detour the function calls you are concerned about:

 

https://github.com/MahdiSafsafi/DDetours

 

You can hook all of the relevant API calls and return whatever values you want.

  • Like 4

Share this post


Link to post
2 hours ago, Brandon Staggs said:

Rather than editing SysUtils (and having to keep your changes up to date every time you upgrade Delphi), Detour the function calls you are concerned about:

If you can do this with detours then it's preferable by far

Share this post


Link to post
On 4/30/2024 at 8:46 PM, Anders Melander said:

Now you just need to add the path of all the VCL/RTL units that use that unit so you can avoid "F2051 Unit XXX was compiled with a different version of YYY" - or make sure that you don't modify the interface section.

If it's really about the interface section, then i have tested the same without modifying interface section. I just created a new function in implementation section and tried to call the newly added function in our sample app. It also gives me the same error.

Share this post


Link to post
20 minutes ago, sp0987 said:

If it's really about the interface section, then i have tested the same without modifying interface section. I just created a new function in implementation section and tried to call the newly added function in our sample app. It also gives me the same error.

If you modify a unit's interface, you have to recompile everything that uses that unit.

 

If you add functionality to a unit's implementation, you can't access it from other units without exposing it in the interface. Catch-22.

 

Best option is to not modify system/rtl units except for non-interface bug fixes. If you need custom functionality, best to just implement it in your own unit.

Share this post


Link to post
34 minutes ago, sp0987 said:

If it's really about the interface section

It must also be compiled with the same settings as the original unit. Hence my hint to the BuildRTL projects.

Share this post


Link to post

Hi,

 

I looked into the detours, its definitely a cool feature but I'm not sure it will solve our dilemma. With some (coding) effort detours may intercept the few system's DateTime functions within our project units, but what about 3rd party units, code and components? They will probably be still using the core sysUtils with original functionality. This may introduce bugs as the app will use 2 different times (ours, and OS).

 

Is there a way (place in Delphi) we could easily (without recompiling RTL/VCL) override the few sysUtils's functions? Or this exactly can be accomplished with proper implementation of detours?

 

Share this post


Link to post
7 minutes ago, sp0987 said:

They will probably be still using the core sysUtils with original functionality

No. You detour the sysutils functions and all code in your process is impacted. 

 

8 minutes ago, sp0987 said:

Is there a way (place in Delphi) we could easily (without recompiling RTL/VCL) override the few sysUtils's functions?

Yes, detours. 

Share this post


Link to post
12 minutes ago, sp0987 said:

but what about 3rd party units, code and components? They will probably be still using the core sysUtils with original functionality.

And what about code that doesn't use RTL functions at all? How are you handling code that calls Windows date/time functions directly? Detours will allow you to hook those calls at the process level. You could modify all of the return values for any of those functions. An RTL call to Now just ends up calling the Windows GetLocalTime function anyway. Hook the GetLocalTime function and return whatever values you want. No need to mess with SysUtils.

Share this post


Link to post
3 minutes ago, David Heffernan said:

No. You detour the sysutils functions and all code in your process is impacted. 

If detours take care of this than that would be exactly what I need! I will attach detours in main's object constructor and test even 3rd party code goes through them. Thank you all for this suggestion!

Share this post


Link to post
Posted (edited)
19 minutes ago, Brandon Staggs said:

Hook the GetLocalTime function and return whatever values you want. No need to mess with SysUtils.

Thanks for this suggestion too. GetLocalTime is just reference into external Windows DLL in Windows unit I think. I'll need to create a wrapper with same name around it with additional logic somewhere within my project which can be reached by the original GetLocalTime in sysUtils?

 

Correction: it doesn't need to have same name. I could do something like:

 

// excuse wrong code as I do not have D11 in front of me

createNewDetour(@Window.GetLocalTime, @myNewLocalTime, ...);

 

yes?

Edited by sp0987
improved original question

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×