大侠帮一下刚摸到DELPHI门的人把!关于DLL(50分)

  • 主题发起人 主题发起人 northwindrocker
  • 开始时间 开始时间
N

northwindrocker

Unregistered / Unconfirmed
GUEST, unregistred user!
我看《d6编程人员指南》中对把FORM做成DLL调用的例子!书中讲到的是把日历做为一个DLL然后在主程序里调用。源码如下:<br>Calendarlib.drp<br>{*******************************************}<br>library CalendarLib;<br><br>uses<br>&nbsp; ShareMem,<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; DLLFrm in 'DLLFrm.pas' {DLLForm};<br><br>exports<br>&nbsp; ShowCalendar;<br>&nbsp; <br>begin<br>end.<br><br>{********************************}<br>Dllfrm.pas<br><br>{********************************}<br>{ Copyright ?2001 Delphi 6 Developer's Guide Xavier Pacheco<br>&nbsp; and Steve Teixeira }<br><br>unit DLLFrm;<br><br>interface<br><br>uses<br>&nbsp; SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,<br>&nbsp; Forms, Dialogs, Grids, Calendar;<br><br>type<br><br>&nbsp; TDLLForm = class(TForm)<br>&nbsp; &nbsp; calDllCalendar: TCalendar;<br>&nbsp; &nbsp; procedure calDllCalendarDblClick(Sender: TObject);<br>&nbsp; end;<br><br>{ Declare the export function }<br>function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime; StdCall;<br><br>implementation<br>{$R *.DFM}<br><br>function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;<br>var<br>&nbsp; DLLForm: TDllForm;<br>begin<br>&nbsp; // Copy application handle to DLL's TApplication object<br>&nbsp; Application.Handle := AHandle;<br>&nbsp; DLLForm := TDLLForm.Create(Application); <br>&nbsp; try<br>&nbsp; &nbsp; DLLForm.Caption := ACaption;<br>&nbsp; &nbsp; DLLForm.ShowModal;<br>&nbsp; &nbsp; Result := DLLForm.calDLLCalendar.CalendarDate; // Pass the date back in Result<br>&nbsp; finally<br>&nbsp; &nbsp; DLLForm.Free;<br>&nbsp; end;<br>end;<br><br>procedure TDLLForm.calDllCalendarDblClick(Sender: TObject);<br>begin<br>&nbsp; Close;<br>end;<br><br>end.<br><br>然后是主程序:<br>CalendarTest.drp<br><br>mainfrm<br><br>{ Copyright ?2001 Delphi 6 Developer's Guide Xavier Pacheco<br>&nbsp; and Steve Teixeira }<br><br><br>unit MainFfm;<br><br>interface<br><br>uses<br>&nbsp; SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,<br>&nbsp; Forms, Dialogs, StdCtrls;<br><br>type<br>&nbsp; { First, define a procedural data type, this should reflect the<br>&nbsp; &nbsp; procedure that is exported from the DLL. }<br>&nbsp; TShowCalendar = function (AHandle: THandle; ACaption: String): TDateTime; StdCall;<br><br>&nbsp; { Create a new exception class to reflect a failed DLL load }<br>&nbsp; EDLLLoadError = class(Exception);<br><br>&nbsp; TMainForm = class(TForm)<br>&nbsp; &nbsp; lblDate: TLabel;<br>&nbsp; &nbsp; btnGetCalendar: TButton;<br>&nbsp; &nbsp; procedure btnGetCalendarClick(Sender: TObject);<br>&nbsp; end;<br><br>var<br>&nbsp; MainForm: TMainForm;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TMainForm.btnGetCalendarClick(Sender: TObject);<br>var<br>&nbsp; LibHandle &nbsp; : THandle;<br>&nbsp; ShowCalendar: TShowCalendar;<br>begin<br><br>&nbsp; { Attempt to load the DLL }<br>&nbsp; LibHandle := LoadLibrary('CALENDARLIB.DLL');<br>&nbsp; try<br>&nbsp; &nbsp; { If the load failed, LibHandle will be zero.<br>&nbsp; &nbsp; &nbsp; If this occurs, raise an exception. }<br>&nbsp; &nbsp; if LibHandle = 0 then<br>&nbsp; &nbsp; &nbsp; raise EDLLLoadError.Create('Unable to Load DLL');<br>&nbsp; &nbsp; { If the code makes it here, the DLL loaded successfully, now obtain<br>&nbsp; &nbsp; &nbsp; the link to the DLL's exported function so that it can be called. }<br>&nbsp; &nbsp; @ShowCalendar := GetProcAddress(LibHandle, 'ShowCalendar');<br>&nbsp; &nbsp; { If the function is imported successfully, then set lblDate.Caption to reflect<br>&nbsp; &nbsp; &nbsp; the returned date from the function. Otherwise, show the return raise<br>&nbsp; &nbsp; &nbsp; an exception. }<br>&nbsp; &nbsp; if not (@ShowCalendar = nil) then<br>&nbsp; &nbsp; &nbsp; lblDate.Caption := DateToStr(ShowCalendar(Application.Handle, Caption))<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; RaiseLastWin32Error; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; finally<br>&nbsp; &nbsp; FreeLibrary(LibHandle); // Unload the DLL.<br>&nbsp; end;<br>end;<br><br>end.<br>然后我编译DLL运行主程序报内存错误,但程序还是能运行。我估计是他的caption用了string的原因(很肤浅不要笑我)。我不知道怎么改它。能帮我看看吗!<br>
 
将string改为widestring就可以了
 
string 改成pchar!
 
我试过改为pchar但是没改好,改的程序完全不能动了,我就是把用到string变量的地方改为PCHAR但是在主程序里面过不去。哪位好心的人改一下源码贴上来吧!谢谢!
 
静态链接不会出错:<br>type<br>&nbsp;TMainForm = class(TForm)<br>&nbsp; &nbsp;lblDate: TLabel;<br>&nbsp; &nbsp;btnGetCalendar: TButton;<br>&nbsp; &nbsp;procedure btnGetCalendarClick(Sender: TObject);<br>&nbsp;end;<br><br>var<br>&nbsp;MainForm: TMainForm;<br><br>&nbsp;function ShowCalendar(AHandle: THandle; ACaption: string): TDate;StdCall; external 'CALENDARLIB.DLL';<br>implementation<br><br>{$R *.DFM}<br><br>procedure TMainForm.btnGetCalendarClick(Sender: TObject);<br>begin<br>&nbsp; &nbsp; &nbsp;lblDate.Caption := DateToStr(ShowCalendar(Application.Handle, Caption));<br>end;
 
&nbsp; DLLForm.ShowModal;<br>&nbsp; &nbsp;//这时Dllform是不是已经被free掉了?下面再取DllForm里的值当然会报错了<br>&nbsp; &nbsp;Result := DLLForm.calDLLCalendar.CalendarDate;
 
在你的dll的.dpr文件里面的use语句下面,第一行写ShareMem,然后再在你的工程(exe文<br>件)的dpr文件里面的use语句下面的第一行也写上ShareMem。这样就不会有问题了。注意,<br>我说的是dpr文件,不是pas文件。
 
后退
顶部