怎样正确释放DLL(50分)

  • 主题发起人 主题发起人 LSS
  • 开始时间 开始时间
L

LSS

Unregistered / Unconfirmed
GUEST, unregistred user!
我在程序中动态调用DLL,用LOADLIBRARY<br>在用FREELIBRARY释放时出错,出来个CPU调试窗口,<br>如果不用FREELIBRARY可以使用,怎样正确释放DLL
 
hehe, 95%是因为你的声明函数不对(哪里漏了stdcall了吧?)
 
这种问题问eyes算找对人了.
 
&lt;pre&gt;&lt;pre class="text"&gt;<br>Another_eYes: 多谢!<br>但是请说的详细一些,我手头查不到关于STDCALL的资料(本人E文不行)<br>我的程序如下:<br>DLL:<br>Function <br>rk(AliasName,UserName,Password:String;HWD:integer;Personid:string):integer;export;<br><br>主模块:<br>procedure TForm1.Button1Click(Sender: TObject);<br>type TRk=Function(AliasName,Username,password:String;Hwd:integer;Personid:string):integer;<br>var RkFunc:TRk;<br>&nbsp; &nbsp; hLib:THandle;<br>begin<br>&nbsp; hLib:=LoadLibrary('RkModule.Dll');<br>&nbsp; if hLib&amp;lt;32 then begin<br>&nbsp; &nbsp; &nbsp;Application.MessageBox('不是一个有效的WIN32程序','提示信息',mb_ok+MB_ICONINFORMATION);<br>&nbsp; &nbsp; &nbsp;exit;<br>&nbsp; end;<br>&nbsp; RkFunc:=TRK(GetProcAddress(hLib,'RK'));<br>&nbsp; if RkFunc('aa','bb','cc',Application.Handle,'dd')=-1 then <br>&nbsp; &nbsp; &nbsp;Application.MessageBox('调用模块产生错误','提示信息',mb_ok+MB_ICONERROR);<br>&nbsp; FreeLibrary(hLib);<br>end;<br>请问应加在何处,作用是什么,<br>&lt;/font&gt;&lt;/pre&gt;<br><br>
 
RkFunc:=TRK(GetProcAddress(hLib,'RK'));<br>改成<br>@RkFunc := getprocaddress(hLib, 'RK');试试
 
Another_eYes:按你的说法不行,出错,请帮忙看看
 
我试运行了一下,没发现你的程序有什么错误。可能是这儿<br>GetProcAddress(hLib,'RK'),而exports中写成了rk小写。<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;^^<br>另外,我用的D5+NT.<br>
 
最好能把rk中的代码贴上来看看.
 
//////////////////<br>library RkModule;<br><br>uses<br>&nbsp; Forms,<br>&nbsp; Func in 'Func.pas';<br><br>exports<br>&nbsp; RK index 1 name 'RK';<br>begin<br>end.<br>///////////////////<br>unit Func;<br><br>interface<br><br>uses<br>&nbsp; forms,SysUtils,Classes, dbtables,RkSel,Rkl,RKb;<br><br>Function RK(AliasName,UserName,Password:String;HWD:integer;Personid:string):integer;export;<br><br>var<br>&nbsp; CurrentPersonID,CurrentPersonName,DefaultSourceLibId,DefaultSourceLibName:String;<br><br>implementation<br><br>Function RK(AliasName,UserName,Password:String;HWD:integer;Personid:string):integer;export;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; Application.handle:=HWD;<br>&nbsp; &nbsp; Application.CreateForm(TForm_Buy, Form_Buy);<br>&nbsp; &nbsp; Application.CreateForm(TForm_rk, Form_rk);<br>&nbsp; &nbsp; Application.CreateForm(TForm2, Form2);<br>&nbsp; &nbsp; Form_buy.Database1.AliasName:=Uppercase(AliasName);<br>&nbsp; &nbsp; Form_buy.Database1.Params.Clear;<br>&nbsp; &nbsp; Form_buy.Database1.Params.Add(UserName);<br>&nbsp; &nbsp; Form_buy.Database1.Params.Add(Password);<br>&nbsp; &nbsp; Form_buy.Database1.Connected:=true;<br>&nbsp; &nbsp; CurrentPersonID:=Personid;<br>&nbsp; &nbsp; form_buy.showmodal;<br>&nbsp; &nbsp; Form_buy.Database1.Connected:=false;<br>&nbsp; &nbsp; Form2.Free;<br>&nbsp; &nbsp; Form_rk.free;<br>&nbsp; &nbsp; form_buy.free;<br>&nbsp; &nbsp; result:=0;<br>&nbsp; except<br>&nbsp; &nbsp; result:=-1;<br>&nbsp; end;<br>end;<br><br><br>end.<br>请问贴这些够不够,我用的是D4+WIN98+SqlServer7.0<br>程序在运行到FreeLibrary时出来CPU窗口,进行不下去了<br>如果嫌分少,可再加,绝不矢言<br>如果需要将全部程序和库发送过去也行<br><br>
 
我没用Stdcall,一加上程序调用出错<br>我在导出函数名是用的是大写
 
DLL例程和调用例程都要声明成StdCall。<br>例程间参数一致,少用Index。<br>例程参数少用String(尽量不用!),用Pchar代替,很重要!!<br>如要用string,DLL和调用例程都要加上ShareMem单元(DELPHIMM.DLL),<br>还要加在Uses的最前面。
 
看来问题就在string了, 申明成shortstring试试. 最好是pchar.<br>另, dll中:<br>application.handle := hwnd; 这句纯属多余, 去掉它.
 
您说的非常正确,换为pchar后就好使了,不加stdcall为何也好使?<br><br>在调用DLL的函数后马上调用FreeLibrary为何出错:<br>MAIN 在 0167:bff889e1 的模块<br>&nbsp;KERNEL32.DLL 中导致无效页错误。<br>Registers:<br>EAX=c00309f8 CS=0167 EIP=bff889e1 EFLGS=00010212<br>EBX=03caff8c SS=016f ESP=03bafff4 EBP=03bb0000<br>ECX=816656b0 DS=016f ESI=81672b7c FS=46ef<br>EDX=bff768d5 ES=016f EDI=03bb00a8 GS=0000<br>Bytes at CS:EIP:<br>53 56 8b 0d e0 ad fc bf 57 33 f6 8b 38 8b 19 89 <br>Stack dump:<br>在中间加一段延时或放一个messagebox后就不出错了,是何原因,<br>是否没有使用完就释放的原因?<br>这个问题解决完马上加分
 
Another_eYes及众大侠:<br>RkFunc:=TRK(GetProcAddress(hLib,'RK'));<br>if RkFunc(pchar(Database1.AliasName),pchar(Database1.Params[0]),pchar(Database1.Params[1]),pchar('000001'))=-1 then <br>&nbsp; &nbsp;Application.MessageBox('调用入库模块产生错误','提示信息',mb_ok+MB_ICONERROR);<br>For i:=1 to 100000 do Application.ProcessMessages;<br>FreeLibrary(hLib);<br>为何加入延时就不出毛病了,<br>有何办法能判断调用执行完毕再进行释放hlib<br><br>
 
dll中:<br>&nbsp; &nbsp; Form2.Free;<br>&nbsp; &nbsp; Form_rk.free;<br>&nbsp; &nbsp; form_buy.free;<br>都改成formXXX.release;
 
多谢Another_eYes 大侠在众多问题的鼎力相助,<br>不过换成release仍然不好使<br>&gt;&gt;application.handle := hwnd; 这句纯属多余, 去掉它.<br>如果不加上这句,所调用的DLL会开一新窗口,并且仍能切换回原调用的窗口,<br>由于新窗口是SHOWMODAL,原窗口的一切事件都不响应。<br><br>加上这一句麻烦事又来了,调用完毕后,原窗口自动极小化,并且窗口状态<br>为normal,必须使用HIDE,再使用SHOW,才能使原窗口复原,请问是怎么回事?<br><br>问了这么多问题实在不好意思,结束问题时我会再加100给您,谢谢谢谢谢谢
 
你的要求究竟是什么?<br>你不是调用了form2.showmodal吗? 原窗事件当然不会响应了.<br>
 
我的要求是<br>1、在使用application.handle := hwnd时,<br>如关闭调用的DLL后,原窗口保持原状态,而非极小化,<br>2、不使用延时,调用后释放不出错<br>是不是有点烦<br>
 
后退
顶部