Dll窗体出错(Delphi5开发人员指南例程) ( 积分: 20 )

  • 主题发起人 主题发起人 gooodlife
  • 开始时间 开始时间
G

gooodlife

Unregistered / Unconfirmed
GUEST, unregistred user!
// Dll程序段
var
DLLForm: TDllForm;
OldHandle : THandle;
begin
// Copy application handle to DLL's TApplication object
Oldhandle := Application.Handle;
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(Application);
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal;
Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result
finally
DLLForm.Free;
Application.Handle := Oldhandle;
end;

// 调用程序段
var
LibHandle : THandle;
ShowCalendar: TShowCalendar;
begin

LibHandle := LoadLibrary('CALENDARLIB.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
FreeLibrary(LibHandle); // Unload the DLL.
end;

///////返回时出错
我已经做了保存和返回Handle 的打操作了?
 
// Dll程序段
var
DLLForm: TDllForm;
OldHandle : THandle;
begin
// Copy application handle to DLL's TApplication object
Oldhandle := Application.Handle;
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(Application);
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal;
Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result
finally
DLLForm.Free;
Application.Handle := Oldhandle;
end;

// 调用程序段
var
LibHandle : THandle;
ShowCalendar: TShowCalendar;
begin

LibHandle := LoadLibrary('CALENDARLIB.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
FreeLibrary(LibHandle); // Unload the DLL.
end;

///////返回时出错
我已经做了保存和返回Handle 的打操作了?
 
改为:
var
DLLForm: TDllForm;
OldHandle : THandle;
begin
// Copy application handle to DLL's TApplication object
Oldhandle := Application.Handle;
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(Application);
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal;
Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result
finally
FreeAndNil(DLLForm);
Application.Handle := Oldhandle;
end;
 
一样是出错啊
是在
FreeLibrary(LibHandle); // Unload the DLL.
时出错的
 
改为:
var
DLLForm: TDllForm;
OldHandle : THandle;
begin
// Copy application handle to DLL's TApplication object
Oldhandle := Application.Handle;
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(nil);
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal;
Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result
finally
FreeAndNil(DLLForm);
Application.Handle := Oldhandle;
end;
 
是什么来的啊?
编译通不过啊
 
我是为了加粗, 但没起作用, 去掉它
 
出错的地方是这里

FreeLibrary(LibHandle); // Unload the DLL.

应该是我返回的 Handle 有问题,,,所以出错了
和 Dll Form 的建立和 Free 无关的
 
你的DLL
library
BEGIN
END;
中没有代码?
窗体上是否有数据控件?
 
////全部的代码
///调用窗体
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

unit MainFfm;

interface

uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;

type
{ First, define a procedural data type, this should reflect the
procedure that is exported from the DLL. }
TShowCalendar = function (AHandle: THandle; ACaption: String): TDateTime; StdCall;

{ Create a new exception class to reflect a failed DLL load }
EDLLLoadError = class(Exception);

TMainForm = class(TForm)
lblDate: TLabel;
btnGetCalendar: TButton;
procedure btnGetCalendarClick(Sender: TObject);
end;

var
MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.btnGetCalendarClick(Sender: TObject);
var
LibHandle : THandle;
ShowCalendar: TShowCalendar;
begin

LibHandle := LoadLibrary('CALENDARLIB.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('cccc');
if LibHandle = 0 then
ShowMessage('a')
else
FreeLibrary(LibHandle); // Unload the DLL.
end;
end;

end.

// Dell
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
View-Project 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 DELPHIMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using DELPHIMM.DLL, pass string information
using PChar or ShortString parameters. }
library CalendarLib;

uses
ShareMem,
SysUtils,
Classes,
DLLFrm in 'DLLFrm.pas' {DLLForm};

exports
ShowCalendar;

begin
end.

//////////////
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

unit DLLFrm;

interface

uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Grids, Calendar;

type

TDLLForm = class(TForm)
calDllCalendar: TCalendar;
procedure calDllCalendarDblClick(Sender: TObject);
end;

{ Declare the export function }
function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime; StdCall;

implementation
{$R *.DFM}

function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;
var
DLLForm: TDllForm;
OldHandle : THandle;
begin
// Copy application handle to DLL's TApplication object
Oldhandle := Application.Handle;
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(NIl);
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal;
Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result
finally
FreeAndNil(DLLForm);
//DLLForm.Free;
Application.Handle := Oldhandle;
end;
end;

procedure TDLLForm.calDllCalendarDblClick(Sender: TObject);
begin
Close;
end;

end.
 
纯DLL中包含有窗体本来就会出现很多问题,我提出两个问题看看能不能帮助到你。
第一:参数尽量不要使用string来传递。所以尽量也少使用sharemem,如果要使用工程里也要有,不知道你的工程里有没有。
第二:窗体关闭时根本没有释放。默认close操作是Hide了窗体,并没有释放,你可以在OnClose中Action:=caFree;
 
看错了,你有FreeAndnil(DLLForm),你最好做一个demo,这样解决问题可能要来的容易。
 
其实问题很简单,应该就是string参数的问题,调用接口改一下即可
function ShowCalendar(AHandle: THandle; ACaption: PChar): TDateTime; StdCall;

lblDate.Caption := DateToStr(ShowCalendar(Application.Handle, PChar(Caption)))
 
那个要Demo 的....留个Email我发给他

不是String 和 PChar 的问题......

我试过了
 
你Q我吧
185511468
 
你的程序我试过了。调用和返回都正常,只是在关闭主程序时出错,不知何故,学习。我是在05版下试的。明天有时间再试试。
 
窗口标题这么短,sharemem没有必要,dllform.free就行,不用FreeAndnil(DLLForm),
如果还不行的话,下载我的试验结果吧。
由于网商有反盗链所以无法直接连接文件,只好修改主页供下载, 请在一星期内下载,我可不想永久改成这样。
http://kinneng.go1.icpcn.com/htm/xiazai/index.htm
双击里面的 8888.rar




 
在D7下调试通过,不过要在主程序的USES子句中第一项加上sharemem。程序如下:
program CalendarTest;

uses
sharemem,Forms,
MainFfm in 'MainFfm.pas' {MainForm};

{$R *.RES}

begin
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
 
后退
顶部