S
skyroom007
Unregistered / Unconfirmed
GUEST, unregistred user!
写了一个主程序,调用各个功能模块,一个EXE调用多个DLL<br>采用BDE连接,主FORM建立一个永久性的DATABASE连接,<br>采用数据库别名的方式,每个DLL中的TQUERY都连接这个别名<br>主FORM的程序如下<br> private<br> { Private declarations }<br> FDLLProcList :TDLLProcList;<br><br> public<br> { Public declarations }<br> lpDataNotifyIconData;<br> unm:shortstring; //员工代码<br> bmm:shortstring; //部门代码<br> gsm:shortstring; //公司代码<br> qx:shortstring;<br> procedure ShowDLL(str:string);<br> end;<br><br>var<br> MainForm: TMainForm;<br><br>implementation<br><br>{$R *.dfm}<br>procedure TMainForm.FormCreate(Sender: TObject);<br>begin<br> FDLLProcList:=TDLLProcList.Create;<br> LoginForm:=TFormLogin.Create(self);<br>end;<br><br>procedure TMainForm.FormDestroy(Sender: TObject);<br>begin<br>FDLLProcList.Free;<br>end;<br><br>procedure TMainForm.ShowDLL(str:string);<br>var PP:myproc;<br>begin<br> if FDLLProcList.LoadModule(str,'Load') then<br> begin<br> FDLLProcList.RunModule(str,'Load')(Application,Sessions,nil,unm,bmm,gsm,qx);<br> end else<br> begin<br> Application.MessageBox(Pchar('应用模块 : '+str+' 不存在!'), Pchar(Caption), <br><br>MB_OK+MB_ICONEXCLAMATION+MB_DEFBUTTON1+MB_APPLMODAL);<br> end;<br>end;<br><br>procedure TMainForm.N11Click(Sender: TObject);<br>begin<br>MainForm.ShowDLL('dqdpr');<br>end;<br>end.<br><br>TDLLProcList 为一个公用单元 UNITDLL <br>代码如下<br>unit UnitDLL;<br>interface<br>uses Classes, Windows, Messages, SysUtils, Graphics, Controls, Forms, Dialogs,DBTables, StdCtrls,Menus;<br> Type<br> MyProc=procedure (myHandle:Tapplication;Session1:TsessionList;MenuI:TMenuItem;unm,bmm,gsm,qx:ShortString);<br> TDLLProcList=class(TStringList)<br> private<br> FDLLList :TList;<br> FProcList :TList; <br> FIndex :Integer;<br> FProc :MyProc;<br> public<br> constructor Create ;<br> destructor Destroy ; override;<br> function RunModule(ModuleName,ProcName :String): MyProc;<br> function GetModule: MyProc;<br> function LoadModule(ModuleName,ProcName :String):boolean;<br> end;<br>implementation<br> Type<br> PHandle =^THandle;<br> PMyProc =^MyProc;<br> constructor TDLLProcList.Create;<br> begin<br> FDLLList:=TList.Create;<br> FProcList:=TList.Create;<br> inherited Create;<br> end;<br>destructor TDLLProcList.Destroy;<br> var i:integer;<br> mhandleHandle ;<br> ppMyProcMyProc;<br> begin<br> inherited Destroy;<br> for i:=0 to FProcList.Count-1 do begin<br> ppMyProc:=FProcList.items;<br> FreeMem(ppMyProc);<br> end;<br> for i:=0 to FDLLList.Count-1 do begin<br> mhandle:=FDLLList.items;<br> freelibrary(mhandle^); freeMem(mhandle);<br> end;<br> FDLLList.Free;<br> FProcList.Free;<br> end;<br><br>function TDLLProcList.RunModule(ModuleName,ProcName :String): MyProc;<br> begin<br> result:=nil;<br> if LoadModule(ModuleName,ProcName) then begin<br> GetModule;<br> result :=FProc;<br> end;<br> end;<br><br>function TDLLProcList.LoadModule(ModuleName,ProcName :String):boolean;<br> var i:integer;<br> mhandleHandle ;<br> ppMyProcMyProc;<br> mMyProc :MyProc;<br> mdllname,mp:String;<br> mTHandle:THandle;<br> begin<br> result:=false;<br> i:=IndexOf(ModuleName+':'+ProcName);<br> if i>-1 then begin<br> FIndex := i; Result:=True;<br> end else begin<br> mdllname:=Copy(ModuleName,1,length(ModuleName))+'.dll';<br> mTHandle:=LoadLibrary(pchar(mdllname));<br> mp:= Copy(procname,1,length(ProcName));<br> if mThandle<>0 then begin<br> @mMyProc:=GetProcAddress(mTHandle,pchar(mp));<br> if @mMyProc<> nil then begin<br> New(ppMyProc);<br> ppMyProc^:=mMyProc; FProcList.Add(ppMyProc);<br> New(mHandle);<br> mHandle^:=mTHandle; FIndex:=FDllList.Add(mHandle);<br> Add(ModuleName+':'+ProcName); Result:=True;<br> end else Exception.Create('以下调用函数不存在 '+ModuleName+':'+ProcName);<br> end else Exception.Create('以下模块不存在 '+ModuleName+':'+ProcName);<br> end;<br>end;<br><br>function TDLLProcList.GetModule:MyProc;<br>var ppMyProcMyProc;<br> begin<br> ppMyProc := FProcList.Items[FIndex];<br> FProc:=ppMyProc^;<br> Result :=ppMyProc^;<br> end;<br>end.<br><br>调用的DLL的程序如下<br>library dqdpr;<br><br>{ Important note about DLL memory management: ShareMem must be the<br> first unit in your library's USES clause AND your project's (select<br> Project-View Source) USES clause if your DLL exports any procedures or<br> functions that pass strings as parameters or function results. This<br> applies to all strings passed to and from your DLL--even those that<br> are nested in records and classes. ShareMem is the interface unit to<br> the BORLNDMM.DLL shared memory manager, which must be deployed along<br> with your DLL. To avoid using BORLNDMM.DLL, pass string information<br> using PChar or ShortString parameters. }<br><br>uses<br> SysUtils,<br> Classes,<br> DQpas in 'DQpas.pas' {CKDQ};<br><br>{$R *.res}<br>exports<br> Load name 'Load';<br>begin<br>end.<br><br>DLL有一个FORM 有Tquery控件连接BDE别名<br>代码如下<br>unit DQpas;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> Db, DBTables, ImgList, ComCtrls, StdCtrls, ExtCtrls,Menus, DBCtrls,<br> Grids, DBGrids, Buttons, DBSBtn;<br><br>type<br> TCKDQ = class(TForm)<br> DBGrid1: TDBGrid;<br> qry_main: TQuery;<br> DataSource1: TDataSource;<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> MenuItem:TMenuItem;<br> end;<br>procedure Load(App:TApplication;Sessions1:TSessionList;MenuI:TmenuItem;unm1,bmm1,gsm1,qx1:shortstring);export;<br><br>var<br> CKDQ: TCKDQ;<br> unm:shortstring;<br><br>implementation<br><br>{$R *.dfm}<br>procedure Load(App:TApplication;Sessions1:TSessionList;MenuI:TmenuItem;unm1,bmm1,gsm1,qx1:shortstring);export;<br>begin<br> unm:=unm1;<br> Application:=App;<br> Sessions:=Sessions1;<br> with TCKDQ.Create(Application) do begin<br> MenuItem:=MenuI;<br> show;<br> end;<br>end;<br><br>end.<br><br>问题是 如果Tquery空间中没有写任何语句 主程序能调用成功如果写了语句就无法调用了出现如下报错<br>Exception EdatabaseError in module dqdpr.dll at 000715FD<br><br>请教如何解决? 谢谢