带数据的DLL窗体关闭时报非法访问内存地址(100分)

  • 主题发起人 主题发起人 狄克
  • 开始时间 开始时间

狄克

Unregistered / Unconfirmed
GUEST, unregistred user!
我创建一个带数据的DLL窗体,同时有DataModule窗体,窗体关闭时报非法访问内存地址<br>DLL的代码如下:<br>library datadll;<br>uses<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; Forms,<br>&nbsp; Ole2,<br>&nbsp; Unit1 in 'Unit1.pas' {DataModule1: TDataModule},<br>&nbsp; Unit2 in 'Unit2.pas' {Form2};<br><br>{$R *.res}<br>function showme(AHandle:THandle) : string ; stdcall ;<br>begin<br>&nbsp; &nbsp;CoInitialize(nil);<br>&nbsp; &nbsp;DataModule1 := TDataModule1.Create(Application) ;<br>&nbsp; &nbsp;Form2 := TForm2.Create(Application) ;<br><br>&nbsp; &nbsp;Form2.ShowModal ;<br><br>&nbsp; &nbsp;FreeAndNil(DataModule1);<br>&nbsp; &nbsp;FreeAndNil(Form2) ;<br>&nbsp; &nbsp;coUnInitialize;<br>&nbsp; &nbsp;Result := Form2.DBGrid1.SelectedField.AsString ;<br>end ;<br><br>exports<br>&nbsp; &nbsp;showme ;<br>&nbsp; &nbsp;<br>begin<br>end.<br><br>Form2是数据显示主窗体,有一个DBGRID用来显示DataModule中表的内容,没有任何其它代码,<br><br>DataModule的代码如下:<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; SysUtils, Classes, DB, ADODB;<br><br>type<br>&nbsp; TDataModule1 = class(TDataModule)<br>&nbsp; &nbsp; ADOConnection1: TADOConnection;<br>&nbsp; &nbsp; ADODataSet1: TADODataSet;<br>&nbsp; &nbsp; DataSource1: TDataSource;<br>&nbsp; &nbsp; procedure DataModuleCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; DataModule1: TDataModule1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TDataModule1.DataModuleCreate(Sender: TObject);<br>begin<br>&nbsp; &nbsp;if not ADODataSet1.Active then<br>&nbsp; &nbsp; &nbsp; ADODataSet1.Open ;<br>end;<br><br>end.<br><br>调用该DLL的代码如下:<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br><br>type<br>&nbsp; Tshowme = function (AHandle: THandle): string; StdCall;<br>&nbsp; EDLLLoadError = class(Exception);<br><br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; LibHandle &nbsp; : THandle;<br>&nbsp; Showme: Tshowme ;<br>begin<br>&nbsp; LibHandle := LoadLibrary('F:/DATADLLTEST/DLL/DATADLL.DLL');<br>&nbsp; try<br>&nbsp; &nbsp; if LibHandle = 0 then<br>&nbsp; &nbsp; &nbsp; raise EDLLLoadError.Create('Unable to Load DLL');<br>&nbsp; &nbsp; @Showme := GetProcAddress(LibHandle, 'showme');<br>&nbsp; &nbsp; if not (@Showme = nil) then<br>&nbsp; &nbsp; &nbsp; Edit1.Text := Showme(Application.Handle)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; RaiseLastWin32Error;<br>&nbsp; finally<br>&nbsp; &nbsp; FreeLibrary(LibHandle); // Unload the DLL.<br>&nbsp; end;<br>end;<br><br>end.<br><br>请高手指教,得到答案后立即送分<br>在线等待<br>
 
这是因为你的DataModual没有释放,造成内存泄漏:<br>给你一个例子把这个DLL Kill掉(放在调用的程序中):<br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; H:THandle;<br>&nbsp; P:DWORD;<br>begin<br>&nbsp; H:=FindWindow(nil,'无标题 - 记事本');<br>&nbsp; if H&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; GetWindowThreadProcessId(H,@P);<br>&nbsp; &nbsp; if P&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; TerminateProcess(OpenProcess(PROCESS_TERMINATE,False,P),$FFFFFFFF);<br>&nbsp; end;<br>end;
 
我很急,请大家帮忙!!!!
 
你必须退出时把ADODataSet1.close
 
Uses的第一个单元应该是ShareMem,因为你的是Dll用到了String<br>你可以看一下Delphi的帮助
 
以前有这方面的讨论,关键是因为DLL中使用COM的原因。
 
Result := Form2.DBGrid1.SelectedField.AsString ;<br>执行到这句时,Form2已经释放了:FreeAndNil(Form2) ;<br>调换位置即可!!<br>
 
我现在没时间进行过多的测试,先发分。<br>谢谢各位
 
后退
顶部