因工作需要,我们用Delphi创建了一个标准件库DLL文件,内含适应于本行业不同软件项目需要的一些通用函数,以便能在用Delphi、VB、VC、VFP等应用软件中调用。在该标准件库文件的设计与调用过程中,我们发现,针对不同的开发工具DLL文件的设计及其中的函数调用方法是有区别的,但各开发工具相关技术资料都没有对此具体介绍。如果对各种开发工具调用DLL函数的方法没有详细的了解,编程、排错将会遇到许多莫名其妙、百思不得其解的困惑。譬如,我们用DelPhi编制的同一个DLL文件,相关函数在Delphi、VB、VC等开发环境都先后调用成功,但在VFP中调用,却总提示“找不到函数入口”或“函数返回值非法”的错误,苦想几日仍不得要领,最后不得不求助于微软公司和Inprise公司的技术支持才得以解决。
本文就以一个通用的口令对话框函数为例,探讨用DelPhi编制DLL及在不同开发工具中调用DLL函数的方法。
一、用Delphi 4.0创建DLL的步骤
通过Delphi创建DLL动态连接库文件操作流程并不复杂:
1. 创建一个新的DLL项目。单击File/New菜单,在弹出的对话框中选择DLL,再单击OK后,Delphi会自动生成一个工程文件项目。
2. 将项目中的DPR文件中的Program关键字改为Library,申明为动态连接库。
3. 再在DPR文件中的USES语句后加入exports指明调用DLL的函数名。
4. 打开项目中的Pas文件中,Type………End后加入该DLL的函数或过程的声明,形如:FunctionName (argment): Boolean; export;。并正确添加相应的处理代码。
5. 对项目进行编译即可生成相应的DLL文件。
二、DLL编程实例:口令对话框函数
首先,我们设计一个内含口令输入对话框函数(如图1所示)的DLL文件。
口令输入对话框表单各组件及相关属性如下:
………………………………………………………………………
form Name PasswordForm
Label Name prompt
Caption Enter Password:
Edit box Name passwordField
Passwordchar *
Bit-button Name Okbtn
Kind bkOK
Bit-button Name Cancelbtn
Kind bkCancel
当您保存项目时,把口令输入对话框表单单元文件命名为PASSFORM.PAS。把项目文件命名为PASSWORD.PRJ。
表单单元文件PASSFORM.PAS基本框架如下:
unit pass;
interface
uses
…………//自动生成
type
…………//自动生成
end;
var
PasswordForm: TPasswordForm;
function GetPassword(APassword:PChar):integer;export;stdcall;
implementation
{$R *.DFM}
function GetPassword(APassword:PChar):wordbool;
//实现接口函数
begin
result:=false;
passwordform:=Tpasswordform.Create(application);
try
if passwordform.ShowModal = idok then
if comparetext(passwordform.passw
ordfield.text,strpas(apassword))=0 then
result:=true
else
messagedlg('密码无效!',mtwarning,[mbok],0) ;
finally
passwordform.free;
end;
end;
end.
其中,语句function GetPassword(APassword:PChar):integer;export;stdcall;声明接口函数,其后必须后接export指令,来确保DLL能把此例程输出于外部程序。
注意:integer是在VFP中调用时的数据类型,在export后必须加上“stdcall;”;如果是在VB、Delphi4.0、VC中调用,则应定义数据类型为wordbool,并且在export后不需接“stdcall;”关键字。
项目文件PASSWORD.PRJ内容如下:
library password;
{…………}//自动生成
//它包含一个名为GetPassword的接口函数
uses
SysUtils,
Classes,
pass in 'pass.pas' {PasswordForm};
exports
GetPassword;
{$r *.res}
begin
end.
然后,将它们编成PASSWORD.DLL。
三、在不同开发工具中调用DLL函数
在其它开发工具中调用DLL函数时,系统将在执行程序s所在目录、当前Windows及其系统目录System下搜索指定的DLL文件中的函数,如果找到,即执行该DLL函数;否则,认为是无效函数,程序出错。因此,我们在继续下面的讨论之前,我们可以将编译得到的PASSWORD.DLL文件拷入Windows的SYSTEM系统目录下。
3.1在Delphi中调用口令对话框
创建一个简单的项目,在主表单上加入一个命令按钮如Button1,用external引入口令输入对话框函数,再添加它的事件处理程序来使用口令输入对话框,运行之即可实现结果。
源代码如下:
unit Unit1;
interface
uses
………//自动生成
type
………//自动生成
end;
var
Form1: TForm1;
function GetPassword(apassword:pchar):wordbool;far;external 'password';
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if GetPassword('PASS') THEN
color:=clgreen
else
color:=clred;
end;
end.
3.2在VB中调用口令对话框
在VB应用中调用口令对话框方式与Delphi中类似。首先在模块代码中声明外部DLL函数:
Declare Function GetPassword Lib "password" (ByVal lppt As String) As Boolean
然后设置窗体代码如下:
Private Sub Command1_Click()
Form1.Visible = False
If GetPassword("PASS") = True Then
Form1.BackColor = vbBlue
MsgBox "密码输入正确!", , "注册管理"
Form1.Visible = True
Else
Form1.BackColor = vbRed
MsgBox "密码输入不正确!", , "注册管理"
Form1.Visible = True
End If
End Sub
3.3在VC中调用口令对话框
在VC中调用DLL函数,应先在其主程序代码中声明DLL函数,如:
extern BOOL GetPassword(LPSTR);
然后在其它位置即可象内部函数一样调用被声明的DLL函数,例如在某一按钮事件调用:
Void TtestWindows::buttonPressed()
{
if (GetPassword(“PASSWORD”))
SetBkgndColor(Tcolor::LtGreen);
else
SetBkgndColor(Tcolor::LtRed);
Invalidate();
}
注意,在最后的项目编译时,必须对PASSWORD.DLL运行IMPLIB工具,并与*.LIB一起加入应用项目,一起编译。
3.4在VFP中调用口令对话框
在VFP中调用DLL函数,必须首先在程序中声明DLL函数,如:
Declare Integer GetPassword IN "password" String @lcBuffer
其中String @lcBuffer用于定义入口参数变量,该参数实现从VFP向DLL函数的参数传递。变量名前必须加上强制传递符号@,表示传递的是变量的地址而不是变量的值。
然后调用DLL函数,如GetPassword(@lcBuffer)。因为在默认情况下,函数参数按值传递,因此也必须在参数前添加符号@来强制参数按地址传递。
若要注册DLL函数,必须同时指定参数的数目和类型
调用源代码如下:
Lparameter lcBuffer
lcBuffer ="PASS"
CLEAR
Declare Integer GetPassword IN "password" String @lcBuffer
If GetPassword(@lcBuffer)=1 Then
MESSAGEBOX("密码输入正确!注册管理",16)
Else
MESSAGEBOX("密码输不入正确!注册管理",16)
EndIf
针对某一行业或共同的应用领域,编辑标准化的通用DLL文件,确实是提高软件生产效率的一种可行办法。因此,我们在针对不同开发工具开发通用的DLL文件时,一定要对其设计和使用的细微差别多加小心,以免无谓的精力浪费。
|