DllY调用问题(100分)

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

louqing_2

Unregistered / Unconfirmed
GUEST, unregistred user!
我在使用主程序调用DLL后可以显示内容,但是在退出主程序时出错,
提示内容为:Exception EAccessViolation in mode Prorect1.exe at 000230a9.
Access violation at address 004230a9 in module 'Project1.exe', Read of address 01662140
确定
在线等回复

我的DLL程序如下:
library Test;

{ 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
SysUtils,
Classes,
Forms,
Messages,
Windows,
DB,
ADODB,
Dialogs,
Activex,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {DataModule2: TDataModule};

var
//DLLAppHandle: HWND;
//DllScreen: TScreen;

GApplication: TApplication;
GScreen: TScreen;
//sdocon1:Tadoconnection;
//GHintWindowClass: THintWindowClass;


{$R *.res}




procedure ShowForms(AApplication: TApplication;
AScreen: TScreen;
//AHintWindowClass:THintWindowClass;
Acnn:Tadoconnection;
Acaption:PCHAR); stdcall;
var
tmpLongInt: PLongint;
begin
{ 读取主调窗体信息 }
Application := AApplication;
Screen := AScreen;

//HintWindowClass := AHintWindowClass;
{ MainFrom只读,使用指针强行赋值 }
tmpLongInt := @(Application.MainForm);
tmpLongInt^ := Longint(AApplication.MainForm);
{//Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TDataModule2, DataModule2);
form1.ShowModal;
//Application.Run; {}

{}
if not Assigned(Form1) then //是不是已有FORM1窗体
DataModule2:=TDataModule2.Create(Application.MainForm) ;
Form1 := TForm1.Create(Application.MainForm); //增加这个这时就会出错
DataModule2.ADOConnection1:=Acnn;
//form1.ADOStoredProc1.Connection:=form1.ADOConn1;
Form1.Caption:=Acaption; //窗体标题
try
Form1.ShowModal;
except
if DataModule2<>nil then
DataModule2.Free;
if form1<>nil then
Form1.Free;
end; {}
end;
procedure DLLUnloadProc(Reason: Integer);
begin
if Reason = DLL_PROCESS_ATTACH then
begin
CoInitialize(nil);
end
else if Reason = DLL_PROCESS_DETACH then
begin
Application := GApplication;
Screen := GScreen;
CoUninitialize;
end
else if Reason =DLL_THREAD_ATTACH then
begin

end
else if Reason =DLL_THREAD_DETACH then
begin

end;
end;
exports
ShowForms;


begin
GApplication := Application;
GScreen := Screen;
DLLProc := @DLLUnloadProc;
DLLUnloadProc(DLL_PROCESS_ATTACH); ///
end.
//unit2单元内容
unit Unit2;

interface

uses
SysUtils, Classes, DB, ADODB;

type
TDataModule2 = class(TDataModule)
ADOConnection1: TADOConnection;
private
{ Private declarations }
public
{ Public declarations }
end;

var
DataModule2: TDataModule2;

implementation

{$R *.dfm}

end.
//UNIT1内容
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids,Unit2, DBGrids, ADODB, StdCtrls;
type
TForm1 = class(TForm)
ADOStoredProc1: TADOStoredProc;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation



{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ADOStoredProc1.Connection:=DataModule2.ADOConnection1;
showmessage(DataModule2.ADOConnection1.ConnectionString );
showmessage(ADOStoredProc1.Connection.ConnectionString );
ADOStoredProc1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ADOStoredProc1.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
close;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if ADOStoredProc1.Active then ADOStoredProc1.Close;
ADOStoredProc1.Connection:=NIL;

Action:= caFree;

end;

end.

//主程序
unit Unit10;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Unit11,DB, ADODB,shellapi; //, QForms
TYPE
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FDllHandle: THandle;
procedure ShowDLLForm(ADLLName, AProcName: PAnsiChar);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation

{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowDLLForm('test.dll', 'ShowForms');
end;
procedure TForm1.ShowDLLForm(ADLLName, AProcName: PAnsiChar);
var
tmpProc: procedure (AApplication: TApplication;
AScreen: TScreen;
Acnn:Tadoconnection;
Acaption:PCHAR); stdcall;
begin
FDllHandle := LoadLibrary(ADLLName);
try
if FDllHandle >= 32 then
begin
@tmpProc := GetProcAddress(FDllHandle, AProcName);
if not (@tmpProc =nil) then
tmpProc(Application, Screen, DataModule1.ADOConnection1,'我的DLL');
end;
finally
FreeLibrary(FDllHandle);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
try
close;
except
on E: Exception do
begin
showmessage('ShowMenu1: '+E.Message);//, E.HelpContext);
end;
end;
end;

end.
 
没人回我,高手啊,求救了
 
Exception EAccessViolation in mode Prorect1.exe at 000230a9.
Access violation at address 004230a9 in module 'Project1.exe', Read of address 01662140

看提示的内存地址就知道你载卸DLL后还调用了DLL的函数!
 
Writer,可不可告诉我怎么改吗?
 
老问题了,只要加上一条简单的语句就可以解决:
...
{}
if not Assigned(Form1) then //是不是已有FORM1窗体
DataModule2:=TDataModule2.Create(Application.MainForm) ;
Form1 := TForm1.Create(Application.MainForm); //增加这个这时就会出错
DataModule2.ADOConnection1:=Acnn;
//form1.ADOStoredProc1.Connection:=form1.ADOConn1;
Form1.Caption:=Acaption; //窗体标题
try
Form1.ShowModal;
FreeAndNil(Form1) // 强行手动销毁Form1窗体对象,一般调用创建窗体的DLL的主程序在退出时如果出现非法内存访问错误的话,大多数情况下都可以用这个方法解决。
except
if DataModule2<>nil then
DataModule2.Free;
if form1<>nil then
Form1.Free;
end; {}
end;
...
 
后退
顶部