我的动态链接库,为什么每次退出时就会有非法操作。大家在作这方面的时候,
都是怎么作的,是不是我的那个资源没有释放,或其它什么原因。
大家提点意见!代码如下:///////////////////////PRJ//////////////
unit UnitTest;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
type
TUpdateSoft = function(App:TApplication;ALogUser,ALogPwd,AIniAlias:String):integer;
var
Handle:THandle;
UpdateSoft:TUpdateSoft;
begin
Handle:= LoadLibrary('prjFtpWjxz.dll');
//如果DLL不存在
if Handle= 0 then
begin
Application.MessageBox('程序安装出错,找不到所需的文件:prjFtpWjxz.dll','提示',MB_OK);
Exit;
end;
//如果DLL存在
if Handle<> 0 then
begin
@UpdateSoft:= GetProcAddress(Handle, 'UpdateSoft');
//如果该函数存在
if @UpdateSoft<> nil then
begin
Edit1.Text := IntToStr(UpdateSoft(Application, Pchar('gyjc'), Pchar('gyjc'), Pchar('gyjc')));
end else
begin
Application.MessageBox('调用文件下载函数出错!','提示',MB_OK);
Exit;
end;
end;
FreeLibrary(Handle);
end;
end.///////////////////////DLL/////////////
library prjFtpWjxz;uses
ShareMem,
SysUtils,
Classes,
Forms,
Dialogs,
Controls,
iniFiles,
Windows,ComObj,ActiveX,
UnitFtpDM in 'UnitFtpDM.pas' {DMFTP: TDataModule};{$R *.res}
var
OldApp:TApplication;function ConnectDataBase(ALogUser,ALogPwd,AIniAlias:PChar):Boolean;
var
sConnectStr:String;
begin
Result := True;
//设置连接参数 OraOLEDB.Oracle.1
sConnectStr:='Provider=MSDAORA.1'; //连接方式
sConnectStr:=sConnectStr+';Password='+ALogPwd; //口令
sConnectStr:=sConnectStr+';User ID='+ALogUser; //用户名
sConnectStr:=sConnectStr+';Data Source='+AIniAlias; //别名
sConnectStr:=sConnectStr+';Persist Security Info=True'; //安全级别
DMFTP.adoConn.ConnectionString := sConnectStr;
try
DMFTP.adoConn.Connected := True;
except
Result := False;
end;
end;function UpdateSoft(App:TApplication;ALogUser,ALogPwd,AIniAlias:PChar):integer;
begin
Result :=0;
application:=App;
if not ConnectDataBase(ALogUser,ALogPwd,AIniAlias) then
begin
Result := 1;
Exit;
end;
end;exports
UpdateSoft;
procedure LibraryProc(Reason: Integer);
begin
case Reason of
DLL_PROCESS_ATTACH :
begin
CoInitialize(nil);
Application.CreateForm(TDMFTP,DMFTP);
end;
DLL_PROCESS_DETACH :
begin
if DMFTP.adoConn.Connected then
DMFTP.adoConn.Connected := False;
DMFTP.Free;
DMFTP := nil;
CoUninitialize;
Application := oldApp;
end;
DLL_THREAD_ATTACH: begin end;
DLL_THREAD_DETACH: begin end;
end;
end;
begin
OldApp:=Application;
DllProc := @LibraryProc;
LibraryProc(DLL_PROCESS_ATTACH);
end.在此DMFTP为一个数据模块,里面放着一个TAdoconnect和几个TADOQuery对象我一直找不出那里内存没有释放或者其他错误,请大家帮忙看一看!
都是怎么作的,是不是我的那个资源没有释放,或其它什么原因。
大家提点意见!代码如下:///////////////////////PRJ//////////////
unit UnitTest;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
type
TUpdateSoft = function(App:TApplication;ALogUser,ALogPwd,AIniAlias:String):integer;
var
Handle:THandle;
UpdateSoft:TUpdateSoft;
begin
Handle:= LoadLibrary('prjFtpWjxz.dll');
//如果DLL不存在
if Handle= 0 then
begin
Application.MessageBox('程序安装出错,找不到所需的文件:prjFtpWjxz.dll','提示',MB_OK);
Exit;
end;
//如果DLL存在
if Handle<> 0 then
begin
@UpdateSoft:= GetProcAddress(Handle, 'UpdateSoft');
//如果该函数存在
if @UpdateSoft<> nil then
begin
Edit1.Text := IntToStr(UpdateSoft(Application, Pchar('gyjc'), Pchar('gyjc'), Pchar('gyjc')));
end else
begin
Application.MessageBox('调用文件下载函数出错!','提示',MB_OK);
Exit;
end;
end;
FreeLibrary(Handle);
end;
end.///////////////////////DLL/////////////
library prjFtpWjxz;uses
ShareMem,
SysUtils,
Classes,
Forms,
Dialogs,
Controls,
iniFiles,
Windows,ComObj,ActiveX,
UnitFtpDM in 'UnitFtpDM.pas' {DMFTP: TDataModule};{$R *.res}
var
OldApp:TApplication;function ConnectDataBase(ALogUser,ALogPwd,AIniAlias:PChar):Boolean;
var
sConnectStr:String;
begin
Result := True;
//设置连接参数 OraOLEDB.Oracle.1
sConnectStr:='Provider=MSDAORA.1'; //连接方式
sConnectStr:=sConnectStr+';Password='+ALogPwd; //口令
sConnectStr:=sConnectStr+';User ID='+ALogUser; //用户名
sConnectStr:=sConnectStr+';Data Source='+AIniAlias; //别名
sConnectStr:=sConnectStr+';Persist Security Info=True'; //安全级别
DMFTP.adoConn.ConnectionString := sConnectStr;
try
DMFTP.adoConn.Connected := True;
except
Result := False;
end;
end;function UpdateSoft(App:TApplication;ALogUser,ALogPwd,AIniAlias:PChar):integer;
begin
Result :=0;
application:=App;
if not ConnectDataBase(ALogUser,ALogPwd,AIniAlias) then
begin
Result := 1;
Exit;
end;
end;exports
UpdateSoft;
procedure LibraryProc(Reason: Integer);
begin
case Reason of
DLL_PROCESS_ATTACH :
begin
CoInitialize(nil);
Application.CreateForm(TDMFTP,DMFTP);
end;
DLL_PROCESS_DETACH :
begin
if DMFTP.adoConn.Connected then
DMFTP.adoConn.Connected := False;
DMFTP.Free;
DMFTP := nil;
CoUninitialize;
Application := oldApp;
end;
DLL_THREAD_ATTACH: begin end;
DLL_THREAD_DETACH: begin end;
end;
end;
begin
OldApp:=Application;
DllProc := @LibraryProc;
LibraryProc(DLL_PROCESS_ATTACH);
end.在此DMFTP为一个数据模块,里面放着一个TAdoconnect和几个TADOQuery对象我一直找不出那里内存没有释放或者其他错误,请大家帮忙看一看!
第二:加不加shareMem,在这个程序中都不会出错。
修改以后得出的结论:
一:主程序和DLL中都选用Build with Runtime packages编译,不去掉ShareMem
调用时候报错"0x000000000"指令引用的"0x0000000"内存。该内存不能为"read"
二:主程序和DLL中都选用Build with Runtime packages编译,而且去掉ShareMem
程序运行正常!!!不过我不知道为什么,请帮我解释一下好吗?
为什么要去掉ShareMem(如果我用String的话sharemem是必需要的)!
为什么主程序和DLL中都选用Build with Runtime packages编译,Build with Runtime packages编译起什么作用?
用包时就用Build with runtime package
那么你应设法将其关闭,否则会报错。
如果是MDI FORM ,你可以在主窗体的ONCLOSE事件中加以下代码:
var
i:integer;
begin
for i := 0 to mdichildcount -1 do
mdichildren[i].close;
....
end;
调用时候报错"0x000000000"指令引用的"0x0000000"内存。该内存不能为"read"
我怎么这样用没有问题?是不是你的操作系统有问题了,该重装了。
请你帮我解答这个问题好吗:为什么主程序和DLL中都选用Build with Runtime packages编译,Build with Runtime packages编译起什么作用?
再没有安装Delphi的机器上我运行此Exe和Dll,需要什么BPL?如果用其他语言(如C)调用此DLL,需要BPL吗?