2013-03-16 77 views
9

I'm宣布MidasLib避免一些客户造成MIDAS.DLL DLL地狱。MidasLib.dcu使应用程序变慢

以下代码在2350ms左右运行。如果我在使用中删除了MidaLib声明,它将在45ms内开始运行!

data.xml文件的保存与TClientDataSet.SaveToFile方法,有5000条记录,其大小约的600Kb。

有谁知道如何解释这种怪异的行为?

我可以证实在Delphi XE2 UPD 3和德尔福XE3 UPD 2.

感谢的问题。

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. 
+6

现有bug报告http://qc.embarcadero.com/wc/qcmain.aspx ?d = 109476,http://qc.embarcadero.com/wc/qcmain.aspx?d=107346 – bummi 2013-03-16 13:15:36

+0

哪个版本的Delphi? – 2013-03-16 13:37:25

+0

而正在使用Midas.dll的哪个版本? – afrazier 2013-03-16 13:53:12

回答

6
+0

注意[QualityCentral现在已经关闭] (https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward),所以你不能访问'qc.embarcadero.com'链接了。如果您需要访问旧的QC数据,请查看[QCScraper](http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/)。 – 2017-06-09 17:20:42

0

我不知道为什么你认为你需要使用MidasLib来“避免DLL地狱”。

当RTL调用TCustomClientDataSet.CreateDSBase时,这会在DSIntf.Pas中调用CheckDbClient。这是通过检查注册表来确定哪个实例的Midas.Dll加载的例程。

所以,你可以确保MIDAS.DLL的特定实例用来通过确保注册表反映其位置CheckDbClient被调用之前。 HK_Classes_Root\CLSId\{9E8D2FA1-591C-11D0-BF52-0020AF32BD64}下的注册表设置为InProcServer32。它可以通过调用指定Midas路径和文件名的RegisterComServer进行更新,当然,必须满足必要的注册表访问权限。

+0

好吧,他确实有过这样的情况:有些程序或者用自己的DLL覆盖系统全局DLL,或者在卸载时删除了库。 也有非Borland的实现,基于vgLib的早期工作,尽管它们只与一个人分发并且他的项目不是盒子产品,所以我猜想遇到它的机会是无限小的 – 2017-05-17 16:26:46

+0

@ Arioch'The。谢谢。其实,我发布这个的原因是,前一段时间我被第三方软件包绊住了,安装了一个过时的Midas.Dll,并且花了我很长时间才找到问题的根源,直到我意识到已经发生过。 vgLib?我隐约记得在D5/D7时代附近有一个第三方的Midas克隆;我想知道它是否相关。 – MartynA 2017-05-17 16:41:39

+0

最有可能。弗拉基米尔Gaitanov退出德尔福,他虽然在此之前销售他的克隆(vgLib 1是FLOSS,vgLib 2,这个midas是商业)。至少有一个人在退出时并没有停下来,并继续维护和更新他的克隆。但他当然只能使用它,不要放弃或开放它。 – 2017-05-17 16:44:44

0

我们只是使用迈达斯DLL的本地副本,无论是什么安装在系统中,只有回落到全球性的,如果当地的一个也没有找到。

我们使用XE2 upd4 HF1,我们后来改用XE4的迈达斯DLL(主要项目仍与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.