SilkTest点滴13 – 调用DLL

一个DLL文件(有.dll扩展名)和DLL代表动态链接库。一个DLL文件是一个编译过的函数,对象,和类的集合。DLL可以被用来节约内存的使用,你可以在你的程序中装载需要的DLL然后按照期望的那样使用它们,而不是在每个程序中都定义所有的代码,这意味着同一个DLL可以被多个不同的程序所使用。

 

那么为什么在SilkTest中需要调用一个DLL呢?这是因为Silktest所使用的脚本语言4Test可能没有你对特定对象操作时需要用到的所有的函数,因此,你可能需要使用外部的函数来使用这种对象。通过DLL文件调用这些函数可以做到这一点。

 

在4Test中使用dll有很多好处,其一就是你能使你的代码更加强大。只要你可以导入能够处理那些对象的dll,你就可以访问外部的功能。另一个是可移植性,你可以建立在多个不同脚本和环境中使用的dll。一个dll可以被不同的人在许多不同的脚本中使用。

 

Dll主要被用来添加那些silktest不支持的函数功能。例如,在PageList类中,silktest无法得到pageList对象或者特定标签的RECT里面有多少行,不过,在windows API中有函数可以得到这些信息。但是API中的函数使用的数据类型4Test不支持,所以你需要建立一个dll调用他们并且使用silktest支持的数据类型将需要的信息返回给4Test。

 

那么具体如何在silktest中调用DLL呢?大家可以参照下面的这个4Test语言调用dll的模板。

 

dll dllname.dll

 

             prototype

 

             [prototype]…

 

而下面是一个用4Test调用dll锁住工作站的简单例子。

 

[-] dll “user32.dll”

 

       [ ] int LockWorkStation ()

 

[ ]

 

[-] testcase WorkStationLock () appstate none

 

       [ ]

 

       [ ] LockWorkStation()

 

       [ ]

 

[ ]

 

注意:你可以从4Test脚本调用DLL函数,但是不能调用dll中的成员函数,这是因为silktest只能认出dll通过Export表暴露出来的函数。你无法调用成员函数,因为可能它仅仅是被用来为其他dll函数服务并且是独立运行的。

 

silktest只能处理标准的windows dll,对于非标准的windows 程序映像,silktest将返回一个出错消息。Silktest只能使用c/C++编写的标准windows dll。Silktest无法使用visual basic编写的dll,这是因为,虽然wisual basic 虽然可以用来建立ActiveX dll,但是它无法像visual c++一样建立标准windows dll 。

 

但是dll并非一定要用c或者c++编写。dll中所有可调用的函数必须和一个接口保持一致。如果它是一个可以被任何程序调用的外部函数或者事件,你需要找出外部符号名称,然后可以像dll调用那样调用它。所以,一个技巧就是,找出事件或者函数的外部名称。这样你就可以在4Test中声明和调用它。而4Test拥有的唯一直接访问VB对象的机制是通过GUI外部的属性和方法。所以,通过上面简单的讨论,在VB程序中没有办法调用一个事件。

 

下面的文件是一些在4Test中调用dll的例子。
WorkLock.t文件是一个锁定工作机的例子。

 

[-] dll “user32.dll”

 

       [ ] int LockWorkStation ()

 

[-] testcase WorkStationLock () appstate none

 

       [ ] LockWorkStation()
winClose.t文件是一个关闭窗口的例子。
[-] dll “user32.dll”

 

       [ ] int CloseWindowStation(Long hWinSta)

 

[ ]

 

[-] testcase WinClose() appstate none

 

       [ ] int hWinSta= 1

 

       [ ] CloseWindowStation(hWinSta)
SysExecuteAlternative.t文件是一个SysExecute的例子。

 

[ ] // An alternative to SYS_Execute which uses ShellExecuteA called from the DLL “shell32”.

 

[ ] // This code returns control back to SilkTest unlike SYS_Execute.

 

[ ] // Call the function from the windows API and set the prototype

 

[-] dll “shell32”

 

       [] int ShellExecuteA (int hwnd, String lpOperation, String lpFile, string lpParameters,String lpDirectory, int nShowCmd)

 

[ ]

 

[ ]

 

[-] testcase ShellExe() appstate none

 

       [ ] // Sets iHandle = to the window handle for the desktop

 

       [ ] int iHandle = Desktop.GetHandle()

 

       [ ] // The operation that is to be carried out

 

       [ ] string lpOperation = “open”

 

       [ ] // The file on which this operation will be carried out

 

       [ ] string lpFile = “iexplore”

 

       [ ] // Any additional parameters to the commandline

 

       [ ] string lpParameters = ” “

 

       [ ] // The working directory in which this will be run

 

       [ ] string lpDirectory = “C:/Program Files/Internet Explorer”

 

       [ ] // a flag that determines how the command will be shown

 

       [ ] int iShowCmd = 5

 

       [ ] ShellExecuteA (iHandle,lpOperation,lpFile,lpParameters,lpDirectory,iShowCmd)
关于别名:

 

如果一个函数和4Test保留字同名,或者函数只有序数名,你需要在4Test的声明里面使用别名语句重新命名它。例如,exit已经被4Test编译器保留了,而你又需要调用一个名为exit的函数。你需要用另外的名字声明它,添加一个alias声明,就象下面的样子。

 

dll “mydll.dll”

 

          my_exit ()

 

          alias exit
Dll和用户对象:
dll提供了另一种途径访问用户对象的方法和属性。使用dll语句在4Test中声明一个动态链接库并且定义它的函数原型,一个函数可以像4Test内置函数那样被调用。例如,user32.dll中的SendMessage函数在SetText和TypeKeys拒绝工作的时候用来在Text Field中输入一个字符串。仅仅需要使用ClipBoard.SetText(“some string”)把该字符串拷贝到粘贴板,然后像下面这样使用API消息WM_Paste调用SendMessage:

 

SendMessage(MyWindow.hWnd, WM_PASTE, 0,0).

 

这样的组合语句将得到粘贴板上的内容把它们贴到顽固的TextField上。用户空间经常需要对SendMessage做出响应,但是这要求消息被发送。你可能需要咨询用户对象的开发者从而得到消息的名字和需要的参数。
那么哪些数据类型可以传给DLL中的函数呢?

 

调用C/C++编写的DLL函数,需要使用合适的C数据类型。4Test支持下面的数据类型。

 

C Data Type
Size (byte)
4Test Equivalent
Char
1
String
Int
4
Integer
Short
2
Integer
Long
4
Long
Unsigned Char
1
String
Unsigned int
4
UINT
Unsigned Short
2
UINT
Unsigned long
4
Long
Float
4
Number
Double
8
Number

 

除此以外,你还可以传入由上面的数据类型组成的数组或者记录(但是不能是记录的数组)。如果其他任何数据类型被传入DLL中的函数,将会产生一个错误。

 

不过你也不可以传递一个指针和对象给DLL中的函数。Silktest不能处理COM DLL,因为如果一个COM DLL中的函数没有被导出,silktest就无法访问他们。COM可能不导出函数,因为对COM任何处理都是通过接口进行,这就意味着不可以进行DLL调用。
最后列出一些在silktest中调用DLL函数的过程中常见错误信息,让我们对它们进行简单的分析。

 

下面是一个最常见的错误消息:

 

1.Error Message: *** Error: DLL cannot be loaded Error 126

 

该错误可能的原因是silktest无法找到DLL。请确保你的DLL被指定了完整的路径名,不要使用相对路径,例如:不要用“.”来表示当前目录。
2.Error Message: *** Error: Function SftTree_GetHeader_Col not found in <DLL path and name>

 

该可能的原因是silktest无法找到函数。请确保你的函数名称拼写正确,确保你的函数被DLL导出了。你可以使用Quick View打开DLL,然后查看导出表,确保该函数在导出表中,因为silktest只能看到那些在DLL导出表中的函数。
3.Error Message: *** Error: Exception in DLL call — Function <function name>: code <hex #>, flags <hex #>, address <hex #>

 

该可能的原因是4Test对于函数的声明不正确。请按照你的DLL函数原型在4Test中声明该函数,确保函数的参数个数和参数类型都正确。

 

如果函数被加载进入应用程序的进程空间而不是silktest的进程空间,你必须在声明DLL的时候使用inprocess关键字。

 

Leave a comment

请输入正确的验证码