手把手教你TestComplete_调用标准dll实例

来源:互联网 发布:数据挖掘面试题目 编辑:程序博客网 时间:2024/04/30 20:03

 

 

 本来有些犹豫,要不要写dll调用方法的,因为两个原因,一则已经见到有类似的文章,二则新版本的TestComplete改变了调用方法,我的这个法子是版本7.52的。后来看完了网上的文章,觉得还是写一写,因为网上的文章都基本上是描述的TestComplete的帮助文档的例子,虽然很详细,但是缺点是平常人可能用不到那么复杂的结构,越简单的往往越有生命力。所以这篇文章是从dll编写开始入手写的,重点就只讲了数值和字符串两种类型的调用方法,只要你够倔,日常工作中足够对付了。

好吧,那我们就开工吧。


先上传一个delphi编写的程序,是用来生成dll的:

http://download.csdn.net/source/3515429

 

 

包含了一个delphi程序和编译出来的ProjectDLL.dll,还有程序calldll.txt



文件的内容也非常简单,即便您没做过delphi,也能看个八九不离十,dll随便哪种语言都行,即便VB都可以有法子做的出标准dll,这部分大家看看就好了:


library ProjectDLL;

{ ... }

uses
  SysUtils, Classes;

{$R *.res}

{----编写---}
function INC(X,Y double) double;stdcall;
begin
Result:= X+Y;
end;

function TestStr(pin,pout:pchar):Integer;stdcall;
const
  Title = ' +Title';
var
  str1:string;
begin
  str1:=strpas(pin);
  str1:='modify '+str1+Title;
  strcat(pout,pchar(str1));
  result:=1;
end;


exports  INC,TestStr;
{----编写---}

begin
end.

编译后生成了ProjectDLL.dll,创建一个TestComplete的项目,然后建立一个dll目录,把这个文件拷贝进去。

先看看如何调用double的函数,两个大的步骤:定义和调用

定义部分
dim x,y,z
dim Def_DLL,Def_Proc,Lib

Set Def_DLL = DLL.DefineDLL("ProjectDLL")
Def_Proc=Def_DLL.DefineProc("INC",vt_r8,vt_r8,vt_r8)

调用部分:
Set Lib = DLL.Load(ProjectSuite.Path & "dll\ProjectDLL.dll", "ProjectDLL")

x=1.0
y=2.0
z=Lib.INC(x,y)

再看看string的函数,步骤一样的:

定义部分:
dim Lppin
dim Lppout
dim Def_DLL,Def_Proc,Lib

Set Def_DLL = DLL.DefineDLL("ProjectDLL")

Def_Proc=Def_DLL.DefineProc("TestStr",vt_lpstr,vt_lpstr,vt_i4 )                                                        

调用部分:

Set Lib = DLL.Load(ProjectSuite.Path & "dll\ProjectDLL.dll", "ProjectDLL")  
Set Lppin = DLL.New("LPSTR", 1024)
Lppin.Text = "pin"
Set Lppout = DLL.New("LPSTR", 1024)

call Lib.TestStr(Lppin,Lppout)
Log.Message("Lppout:" & Lppout.Text)



需要注意的有两点:

1.        数据类型,这个很麻烦,需要您仔细看看帮助

在帮助的章节:Parameter Types for C++ Routines and Structures
详细说明了参数类型

还加上了一句恐怖的注释:
Make sure you specified the parameter types correctly. Incorrect definition of parameter types may crash TestComplete (this happens because erroneous definitions cause incorrect stack processing).

确信你的参数声名了正确的数据类型,否则可能你的TestComplete会挂掉。


Type Constant
bool  vt_b1  
BSTR  vt_bstr (see also Calling Functions That Return String Values or Interface References)  
BSTR *  vt_byref | vt_bstr  
Byte  vt_ui1  
Byte *  vt_byref | vt_ui1  
char  vt_i1  
char *  vt_lpstr or vt_byref | vt_i1  This type is supported for function parameters only. The char * result type is not supported.
CY  vt_cy  
CY *  vt_byref | vt_cy
DATE  vt_date
DATE *  vt_byref | vt_date
DECIMAL *  vt_bstr | vt_decimal
double  vt_r8
double *  vt_byref | vt_r8
float  vt_r4
float *  vt_byref | vt_r4
IDispatch *  vt_dispatch
IDispatch **  vt_byref | vt_dispatch
int  vt_int
int *  vt_byref | vt_int
long  vt_i4
long *  vt_byref | vt_i4
SCODE  vt_error
short  vt_i2
short *  vt_byref | vt_i2
unsigned int  vt_uint
unsigned int *  vt_byref | vt_uint
unsigned long  vt_ui4
unsigned long *  vt_byref | vt_ui4
unsigned short  vt_ui2
unsigned short *  vt_byref | vt_ui2
VARIANT  vt_variant
VARIANT *  vt_byref | vt_variant
VARIANT_BOOL  vt_bool
VARIANT_BOOL *  vt_byref | vt_bool
void *  vt_byref | vt_void
wchar_t  vt_ui2
wchat_t *  vt_byref | vt_ui2 or vt_lpwstr This type is supported for function parameters only. The wchar_t * result type is not supported.


看了看,哎哟,我的double应该声名为vt_r8,还好还好,我的TestComplete没挂掉,还执行正确了,这个要看人品的,开玩笑的,其实是要看类型的宽度。我的建议是怎么简单怎么用。另外这个是C++的类型哈,别以为就是你编写语言的。有个类型转换的问题。没事,蒙吧,没挂掉就行了。


2. 注意什么时候必须使用函数,而不是过程

'vt_lpstr:This type is only supproted for function parameters. The PChar result values are not supported

vt_lpstr:这个数据类型只能做为函数参数,而且函数的返回值不可以是PChar类型的。知道为啥我的函数定义是:
function TestStr(pin,pout:pchar):Integer;stdcall;

为啥要使用pin传入,pout传出,而不是用函数值直接传出了吧,没法子,TestComplete不支持那种方式。
不可以写成:
function TestStr(pin,pout:pchar): pchar;stdcall;
或者
Procedure TestStr(pin,pout:pchar);stdcall;


好了,大功告成了,大家就依葫芦画瓢吧,能抄是福呀。