//程序运行时,调用DLL没问题,调用完了,释放的时候总是出错:错误提示地址:000000000001不能为读!
//DLL内部程序
library Pshowcalendar;{ 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
sharemem,
SysUtils,
Classes,
UDllFrm in 'UDllFrm.pas' {DllFrm};{$R *.res}
exports
showcalendar,
closecalendar;
begin
end.
//DLL内部的窗体PAS
unit UDllFrm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ExtCtrls;type
TDllFrm = class(TForm)
Panel1: TPanel;
caldllcalendar: TMonthCalendar;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure caldllcalendarDblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations } end;
function showcalendar(ahandle: THandle; acaption: string): TDateTime;
stdcall;
procedure closecalendar(aformref: longint); stdcall;var
DllFrm: TDllFrm;
implementationprocedure closecalendar(aformref: longint); stdcall;
begin
if aformref > 0 then
TDllFrm(aformref).Free;
end;function showcalendar(ahandle: THandle; acaption: string): TDateTime; stdcall;
var
dllform: TDllFrm;begin { //这段代码用于模式窗体。
Application.Handle := ahandle;
dllform := TDllFrm.Create(Application);
try
dllform.Caption := acaption;
dllform.ShowModal;
Result := dllform.caldllcalendar.Date;
finally
dllform.Free;
end;
}//下面是用于非模式窗体。
Application.Handle := ahandle;
dllform := TDllFrm.Create(Application);
Result := longint(dllform);
dllform.Caption := acaption;
dllform.Show;
end;{$R *.dfm}procedure TDllFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;procedure TDllFrm.FormDestroy(Sender: TObject);
begin
self := nil;
end;procedure TDllFrm.caldllcalendarDblClick(Sender: TObject);
begin
Close;
end;end.
//外部调用DLL的程序:
unit Umain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
tshowcalendar = function(ahandle: THandle; acption: string): TDateTime;
stdcall;
edllloaderror = class(exception); TMainForm = class(TForm)
btngetcalendar: TButton;
lbldate: TLabel;
procedure btngetcalendarClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.btngetcalendarClick(Sender: TObject);
var
libhandle: THandle;
showcalendar: tshowcalendar;begin
libhandle := loadlibrary('Pshowcalendar.dll');
try
if libhandle = 0 then
raise edllloaderror.Create('unable to load dll');
@showcalendar := GetProcAddress(libhandle, 'showcalendar');
if not (@showcalendar = nil) then
lbldate.Caption := DateToStr(showcalendar(Application.Handle, Caption))
else
raiselastwin32error;
finally
// ShowMessage(IntToStr(libhandle));
// freelibrary(libhandle);
//FreeLibraryAndExitThread(libhandle, 0);
//Application.Free ;
//Application.Destroy;
begin
FreeLibrary(libhandle);
//Application.Terminate;
end; end;
end;procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;end;procedure TMainForm.FormDestroy(Sender: TObject);
begin
self := nil;
end;end.
//注:每次运行到freelibrary()的时候出错!就是这个地方的错!
//DLL内部程序
library Pshowcalendar;{ 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
sharemem,
SysUtils,
Classes,
UDllFrm in 'UDllFrm.pas' {DllFrm};{$R *.res}
exports
showcalendar,
closecalendar;
begin
end.
//DLL内部的窗体PAS
unit UDllFrm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ExtCtrls;type
TDllFrm = class(TForm)
Panel1: TPanel;
caldllcalendar: TMonthCalendar;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure caldllcalendarDblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations } end;
function showcalendar(ahandle: THandle; acaption: string): TDateTime;
stdcall;
procedure closecalendar(aformref: longint); stdcall;var
DllFrm: TDllFrm;
implementationprocedure closecalendar(aformref: longint); stdcall;
begin
if aformref > 0 then
TDllFrm(aformref).Free;
end;function showcalendar(ahandle: THandle; acaption: string): TDateTime; stdcall;
var
dllform: TDllFrm;begin { //这段代码用于模式窗体。
Application.Handle := ahandle;
dllform := TDllFrm.Create(Application);
try
dllform.Caption := acaption;
dllform.ShowModal;
Result := dllform.caldllcalendar.Date;
finally
dllform.Free;
end;
}//下面是用于非模式窗体。
Application.Handle := ahandle;
dllform := TDllFrm.Create(Application);
Result := longint(dllform);
dllform.Caption := acaption;
dllform.Show;
end;{$R *.dfm}procedure TDllFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;procedure TDllFrm.FormDestroy(Sender: TObject);
begin
self := nil;
end;procedure TDllFrm.caldllcalendarDblClick(Sender: TObject);
begin
Close;
end;end.
//外部调用DLL的程序:
unit Umain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
tshowcalendar = function(ahandle: THandle; acption: string): TDateTime;
stdcall;
edllloaderror = class(exception); TMainForm = class(TForm)
btngetcalendar: TButton;
lbldate: TLabel;
procedure btngetcalendarClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.btngetcalendarClick(Sender: TObject);
var
libhandle: THandle;
showcalendar: tshowcalendar;begin
libhandle := loadlibrary('Pshowcalendar.dll');
try
if libhandle = 0 then
raise edllloaderror.Create('unable to load dll');
@showcalendar := GetProcAddress(libhandle, 'showcalendar');
if not (@showcalendar = nil) then
lbldate.Caption := DateToStr(showcalendar(Application.Handle, Caption))
else
raiselastwin32error;
finally
// ShowMessage(IntToStr(libhandle));
// freelibrary(libhandle);
//FreeLibraryAndExitThread(libhandle, 0);
//Application.Free ;
//Application.Destroy;
begin
FreeLibrary(libhandle);
//Application.Terminate;
end; end;
end;procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;end;procedure TMainForm.FormDestroy(Sender: TObject);
begin
self := nil;
end;end.
//注:每次运行到freelibrary()的时候出错!就是这个地方的错!
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货