全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3228
推到 Plurk!
推到 Facebook!

LoadLibrary & FreeLibrary 的關係

缺席
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-18 23:13:55 IP:61.71.xxx.xxx 未訂閱
請問各位!    我現在有一個很困擾的問題查不到原因, 以下是我的部份程式
function TSysUT.LoadDLLSys(DLLName,FunctionName: string;
                           Disk: Char; FormName: string;
                           parm1, parm2, parm3, parm4, parm5:variant): boolean;
          type
              TDLLsys = procedure(parm1, parm2, parm3, parm4, parm5: variant); stdcall;              var FormFound: boolean;
              diskSerial: string;
              xhandle: THandle;
              DLLsys: TDLLsys;
              success: string;
              doRun: boolean;
begin
     success:= '';
     doRun:= True;
     try
     if not FileExists(DLLname) then begin
        Application.MessageBox(pChar('不存在的DLL檔:('+DLLName+')'),'執行錯誤',
                                MB_ICONERROR+MB_OK);
        result:= False;
        exit;
     end;
     xhandle:= LoadLibrary(pChar(DLLName));
     if xhandle <> 0 then begin
        @DLLsys:= GetProcAddress(xhandle,pChar(FunctionName));         // Link
        if @DLLsys <> nil then begin
           ..... 做一些權限判斷
           doRun:= isDesigner;
           if doRun then DLLsys(parm1, parm2, parm3, parm4, parm5);
           try
              FreeLibrary(xhandle); 
           except
              on E:Exception do begin
                 Application.MessageBox(pChar(E.Message),'錯誤',MB_OK);
              end;
           end;
        end;
     end;
     result:= ......
end;
實際的呼叫
DLLfile:= U_VarDef.DllPath+'Right.DLL';
SysUT.LoadDLLsys(DLLfile,'DLL_sRight',AppPath[1],'系統等級設定',
                    U_VarDef.loginLEVEL,'Right',U_VarDef.miniFile,'','');
現在發生一個情況 有一支Cust.Dll及Right.Dll 如果先執行Right.dll 結果會出現 後來追蹤是在FreeLibrary出問題 但很奇怪, 如果我先執行Cust.Dll後, 再退出Cust.Dll, 然後再進入Right.Dll竟然兩支都沒有問題 我不信邪, 關閉主程式, 重新啟動, 再按上面的方式執行, 果然只要執行Right.dll先, 就一定出現錯誤, 只要執行Cust.dll再run Right.Dll就ok! 實在令人很頭痛, 不過這兩支程式都是一樣的寫法, 不知道各位有沒有曾遇到這樣情況, 如何解決? ps:前些日子並不會這樣, 是這幾天complier程式後出現, 原先我懷疑中毒, 用了很多方法查證沒有中毒, 也沒有駭客感染, 我使用的是Delphi5+win2k 謝謝! 以下是我的Dll內容
{project file}    library Right;    { Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }    uses
  ShareMem,
  SysUtils,
  Classes,
  DLLver in '..\..\Dll_UT\DLLver.pas',
  U_VarDef in '..\..\Dll_UT\U_VarDef.pas',
  UT_SYS in '..\..\Dll_UT\UT_SYS.pas' {SysUT},
  P_GetDate in '..\..\Dll_UT\P_GetDate.pas' {Form_GetDate},
  U_Default in '..\Delphi5\U_Default.pas',
  P_Right in 'P_Right.pas',
  D_Right in 'D_Right.pas';    exports
       DLL_sRight;    begin
end.    {function file}    function DLL_sRight(dloginLEVEL, progType, diniFile,
                    eVar4, eVar5: variant): boolean; stdcall;    implementation    uses P_Right, DLLver, U_VarDef, U_Default, UT_Sys;    // 系統等級設定
function DLL_sRight(dloginLEVEL, progType, diniFile,
                    eVar4, eVar5: variant): boolean;
begin
 .....
     try
        Form_Right.ShowModal;
     finally
        Form_Right.Free;
        SysUt.Free;
        DLLver.DebugSL.Free;
     end;
end;    
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-19 00:25:25 IP:61.71.xxx.xxx 未訂閱
嗨! 各位!    我發現一個很重要的地方    在非常多的書籍上都強調使用DLL要加上ShareMem這支pas, 所以我在程式中也都加上了, 然而我"雄雄"將ShareMem給disable重新編譯後, 執行Right居然不會發生錯誤了, 查了一些資料, 我找到一篇資料    http://www.chinaaspx.com/club/topic_11_3941.htm 節錄部份內容 三、当使用了长字符串类型的参数、变量时要引用ShareMem。  Delphi中的string类型很强大,我们知道普通的字符串长度最大为256个字符,但Delphi中string类型在默认情况下长度可以达到2G。(对,您没有看错,确实是两兆。)这时,如果您坚持要使用string类型的参数、变量甚至是记录信息时,就要引用ShareMem单元,而且必须是第一个引用的。既在uses语句后是第一个引用的单元。如下例:  uses  ShareMem,  SysUtils,  Classes;  还有一点,在您的工程文件(*.dpr)中而不是单元文件(*.pas)中也要做同样的工作,这一点Delphi自带的帮助文件没有说清楚,造成了很多误会。不这样做的话,您很有可能付出死机的代价。避免使用string类型的方法是将string类型的参数、变量等声明为Pchar或ShortString(如:s:string[10])类型。同样的问题会出现在当您使用了动态数组时,解决的方法同上所述。 我在主程式內並沒有引用 ShareMem, 而dll檔都是由主程式進行呼叫的, 所以我嘗試了在主程式中加入ShareMem之後, 原有Right.Dll沒有改, 這樣的方式調整後執行Right.Dll(第一次), 不再出現錯誤, 我不知道真正原因是否真如我推測這般, 不過至少不會再有錯誤, 如果各位有詳細的說明, 還不吝指教說明, 謝謝!
系統時間:2024-05-01 7:12:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!