MidasLib.dcu makes the application slower
Asked Answered
C

2

12

I´m declaring MidasLib to avoid dll hell caused by Midas.dll in some clients.

The code below runs in about 2350ms. If I remove the MidaLib declaration in uses it starts to run in just 45ms!!

The data.xml file was saved with TClientDataSet.SaveToFile method, has 5000 records and its size is about 600Kb.

Does anybody knows how to explain this weird behavior?

I can confirm the problem in Delphi XE2 upd 3 and in Delphi XE3 upd 2.

Thanks.

program Loader;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  MidasLib,
  System.SysUtils,
  Winapi.Windows,
  Data.DB,
  Datasnap.DBClient;

var
  cds : TClientDataSet;
  start, stop : Cardinal;
begin
  cds := TClientDataSet.Create(nil);
  try
    start := GetTickCount;
    cds.LoadFromFile('c:\temp\data.xml');
    stop := GetTickCount;
    Writeln(Format('Time elapsed: %dms', [stop-start]));
  finally
    cds.Free;
  end;
end.
Cockatrice answered 16/3, 2013 at 12:40 Comment(8)
existing bugreports qc.embarcadero.com/wc/qcmain.aspx?d=109476 , qc.embarcadero.com/wc/qcmain.aspx?d=107346Boardinghouse
Which version of Delphi?Heterothallic
And exactly which version of Midas.dll is being used?Gael
@Boardinghouse Yeah, it seems that is a knwon bug. Voted it. Apparently, I have to live with it for now, tksCockatrice
@Gael The problem is MidasLib.dcu. Midas.dll works fine.Cockatrice
Is there a question here?Zelaya
Yes, the question is "Does anybody knows how to explain this weird behavior? " in conjunction with title "MidasLib.dcu makes the application slower"Kaiserslautern
Hi please consider to accept an answerDryclean
D
7

It is a known bug/regression, see the QC reports

Dryclean answered 16/4, 2013 at 12:29 Comment(1)
Note that QualityCentral has now been shut down, so you can't access qc.embarcadero.com links anymore. If you need access to old QC data, look at QCScraper.Socher
I
2

We just use local copy of Midas DLL regardless of what is installed in the system, and only falling back to global one, if local one is not found.

We use XE2 upd4 hf1 and we later switched to Midas DLL of XE4 ( main project still is made with xe2 )

// based on stock MidasLib unit

unit MidasDLL;

interface

implementation

uses Winapi.Windows, Winapi.ActiveX, Datasnap.DSIntf, SysUtils, Registry;

// function DllGetDataSnapClassObject(const CLSID, IID: TGUID; var Obj): HResult; stdcall; external 'Midas.DLL';
//var DllGetDataSnapClassObject: function(const CLSID, IID: TGUID; var Obj): HResult; stdcall; //external 'Midas.DLL';
var DllGetDataSnapClassObject: pointer; //external 'Midas.DLL';

const dllFN = 'Midas.DLL'; dllSubN = 'DllGetDataSnapClassObject';
var DllHandle: HMODULE = 0;

function RegisteredMidasPath: TFileName;
const rpath = '\SOFTWARE\Classes\CLSID\{9E8D2FA1-591C-11D0-BF52-0020AF32BD64}\InProcServer32';
var rry: TRegistry;
begin
  Result := '';
  rry := TRegistry.Create( KEY_READ );
  try
    rry.RootKey := HKEY_LOCAL_MACHINE;
    if rry.OpenKeyReadOnly( rpath ) then begin
       Result := rry.ReadString('');
       if not FileExists( Result ) then
          Result := '';
    end;
  finally
    rry.Destroy;
  end;
end;

procedure TryFindMidas;
var fPath, msg: string;
  function TryOne(const fName: TFileName): boolean;
  const  ver_16_0 = 1048576; // $00060001
  var    ver: Cardinal;  ver2w: LongRec absolute ver;
  begin
    Result := false;
    ver := GetFileVersion( fName );
    if LongInt(ver)+1 = 0 then exit; // -1 --> not found
    if ver < ver_16_0 then begin
       msg := msg + #13#10 +
              'Obsolete version found: '+IntToStr(ver2w.Hi) + '.' + IntToStr(ver2w.Lo) + ' in library file ' + fName;
       exit;
    end;
    DllHandle := SafeLoadLibrary(fName);
    if DllHandle = 0 then begin
       msg := msg + #13#10 +
              'Failure loading library ' + fName + '. Maybe this was Win64 DLL or some other reason.';
       exit;
    end;
    DllGetDataSnapClassObject := GetProcAddress( DllHandle, dllSubN);
    if nil = DllGetDataSnapClassObject then begin  // не найдена
       msg := msg + #13#10 +
              'Incompatible library loaded ' + fName + '. Missed function ' + dllSubN;
       FreeLibrary( DllHandle );
       DllHandle := 0;
    end;
    Result := true;
  end;
  function TryTwo(const fName: TFileName): boolean; // seek in the given folder and its immediate parent
  begin
    Result := TryOne(fName + dllFN);
    if not Result then
      Result := TryOne(fName + '..\' + dllFN); // 
  end;
begin
  fPath := ExtractFilePath( ParamStr(0) );
  if TryTwo( fPath ) then exit;

  fPath := IncludeTrailingBackslash( GetCurrentDir() );
  if TryTwo( fPath ) then exit;

  fPath := RegisteredMidasPath;
  if fPath > '' then
     if TryOne( fPath ) then exit;

  msg := 'This program needs the library ' + dllFN + ' version 16.0 or above.'#13#10 +
         'It was not found, thus the program can not work.'#13#10 + #13#10 + msg;
  Winapi.Windows.MessageBox(0, PChar(msg), 'Launch failure!',
         MB_ICONSTOP or MB_TASKMODAL or MB_DEFAULT_DESKTOP_ONLY or MB_TOPMOST );
  Halt(1);
end;


initialization
//  RegisterMidasLib(@DllGetDataSnapClassObject); -- static linking does not work for utilities in sub-folders

  TryFindMidas; // immediately terminates the application if not found
  RegisterMidasLib(DllGetDataSnapClassObject);
finalization
  if DllHandle <> 0 then
     if FreeLibrary( DllHandle ) then
        DllHandle := 0;
end.
Immorality answered 17/5, 2017 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.