Search code examples
delphidelphi-7fastmm

delphi 7, FastMM4 cannot install work around


i am working on an application that uses FastMM4, from sourceforge.net. So i have added the FastMM4.pas to the uses clause right at the beginning. In the application i need to run a batch file after FinalizeMemoryManager; in the finalization of unit FastMM4; like this

  initialization
        RunInitializationCode;

  finalization
        {$ifndef PatchBCBTerminate}
        FinalizeMemoryManager;
        RunTheBatFileAtTheEnd; //my code here..calling a procedure
       {$endif}

 end.

then my code for RunTheBatFileAtTheEnd is :

 procedure RunTheBatFileAtTheEnd;
 begin
 //some code here....
  sFilePaTh:=SysUtils.ExtractFilePath(applicaTname)+sFileNameNoextension+'_log.nam';
 ShellExecute(applcatiOnHAndle,'open', pchar(sExeName),pchar(sFilePaTh), nil, SW_SHOWNORMAL) ;
 end;

For this i need to use SysUtils,shellapi in the uses clause of fastmm4 unit. But using them this message comes enter image description here

But if i remove SysUtils,shellapi from the uses it works. I still need all the features of fastmm4 installed but with SysUtils,shellapi, fastmm4 is not installed

I have a unit of my own but its finalization is executed before fastmm4 finalization.

can anyone tell me can how to fix this problem?

EDIT- 1

unit FastMM4;
//...
...
implementation

 uses
   {$ifndef Linux}Windows,{$ifdef FullDebugMode}{$ifdef Delphi4or5}ShlObj,{$else}
  SHFolder,{$endif}{$endif}{$else}Libc,{$endif}FastMM4Messages,SysUtils,shellapi;

my application

 program memCheckTest;
   uses
      FastMM4,

EDIT-2 :

(after @SertacAkyuz answer),i removed SysUtils and it worked , but i still need to run the batch file to open an external application through RunTheBatFileAtTheEnd. The Reason is ..i want a external application to run only after FastMM4 as been out of the finalization. The sExeName is the application that will run the file sFilePaTh(.nam) . can any one tell how to do this? without uninstalling FastMM4.


Solution

  • FastMM checks to see if the default memory manager is set before installing its own by a call to IsMemoryManagerSet function in 'system.pas'. If the default memory manager is set, it declines setting its own memory manager and displays the message shown in the question.

    The instruction in that message about 'fastmm4.pas' should be the first unit in the project's .dpr file has the assumption that 'fastmm4.pas' itself is not modified.

    When you modify the uses clause of 'fastmm4.pas', if any of the units that's included in the uses clause has an initialization section, than that section of code have to run before the initialization section of 'fastmm4.pas'. If that code requires allocating/feeing memory via RTL, then the default memory manager is set.

    Hence you have to take care changing 'fastmm4.pas' to not to include any such unit in the uses clause, like 'sysutils.pas'.


    Below sample code (no error checking, file checking etc..) shows how can you launch FastMM's log file with Notepad (provided the log file exists) without allocating any memory:

    var
      CmdLine: array [0..300] of Char; // increase as needed
      Len: Integer;
      SInfo: TStartupInfo;
      PInfo: TProcessInformation;
    
    initialization
      ...  // fastmm code
    
    finalization
    {$ifndef PatchBCBTerminate}
      FinalizeMemoryManager;       // belongs to fastmm
    
      // Our application is named 'Notepad' and the path is defined in AppPaths
      CmdLine := 'Notepad "';  // 9 Chars (note the opening quote)
      Len := windows.GetModuleFileName(0, PChar(@CmdLine[9]), 260) + 8;
    
      // assumes the executable has an extension.
      while CmdLine[Len] <> '.' do
        Dec(Len);
    
      CmdLine[Len] := #0;
      lstrcat(CmdLine, '_MemoryManager_EventLog.txt"'#0); // note the closing quote
    
      ZeroMemory(@SInfo, SizeOf(SInfo));
      SInfo.cb := SizeOf(SInfo);
      CreateProcess(nil, CmdLine, nil, nil, False,
                    NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo);
    
    {$endif}
    
    end.