思步网
标题:
LoadRunner下DLL的调用
[打印本页]
作者:
流浪开心果
时间:
2010-12-6 13:41
标题:
LoadRunner下DLL的调用
场景介绍
最近在做类似于QQ的通信工具的性能测试时发现了一些问题,现总结出来与大家分享一下。希望大家在使用LoadRunner时不仅仅停在只是录制/播放角本,而全面提升角本的编程技术,解决复杂场景。
本次测试中碰到的问题是这样的,在消息的传送过程中遇到了DEC加密的过程,LoadRunner录制到的全是加密的消息,比如我录制了某一个用户的登陆,发送消息,退出,但由于是加密的,只能单个用户使用,但如果我想并发多少个用户就存在很多问题,最直接的一个问题就是用户名是加密的,密码是加密的,当然你可以说让程序那里注掉加密的代码进行明码的测试,当然也是一种办法。但程序组提出了要使用更真实的方法来模拟,这时就必需使用下面介绍的方法。
一开始是直接把API移植到LoadRunner中来,不过由于加密算法异常复杂,有几层循环,而角本是解释执行的,进行一次加密运算可能需要好几分钟,当然在角本里可以把角本本身运行的时间去掉,但这样做显然没有直接调用DLL来的效率高。由于程序组比较忙,所以无法提供DLL给测试,所以测试完成了DLL的编写,并在LoadRunner中调用成功,高效的完成了用户信息加密,参数关联,成功的完成了测试。
动态链接库的编写
在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择Win32 Dynamic-Link Library建立一个空的DLL工程。
1. Win32 Dynamic-Link Library方式创建Non-MFC DLL动态链接库
每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。在Non-MFC DLL中DllMain是一个缺省的入口函数,你不需要编写自己的DLL入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的DLL需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的DLL工程的.CPP文件中对DllMain()函数按照下面的格式书写。
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE;
}
参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用、DLL_THREAD_ATTACH: 线程被调用、DLL_PROCESS_DETACH: 进程被停止、DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。到此为止,DLL的入口函数已经写了,剩下部分的实现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。
我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用DEF文件。下面通过两个例子来说明如何使用这两种方法创建DLL文件。
1)使用导出函数关键字_declspec(dllexport)创建MyDll.dll,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在MyDll.h和MyDLL.cpp文件中分别输入如下原代码:
//MyDLL.h
extern "C" _declspec(dllexport) int desinit(int mode);
extern "C" _declspec(dllexport) void desdone(void);
extern "C" _declspec(dllexport) void des_setkey(char *subkey, char *key);
extern "C" _declspec(dllexport) void endes(char *block, char *subkey);
extern "C" _declspec(dllexport) void dedes(char *block, char *subkey);
//MyDll.cpp
#include"MyDll.h"
//这里我用了比较大小的函数代替了我要实现的函数
int desinit(int a, int b)
{
if(a>=b)return a;
else
return b;
}
int desdone(int a, int b)
{
if(a>=b)return b;
else
return a;
}
该动态链接库编译成功后,打开MyDll工程中的debug目录,可以看到MyDll.dll、MyDll.lib两个文件。LIB文件中包含DLL文件名和DLL文件中的函数名等,该LIB文件只是对应该DLL文件的"映像文件",与DLL文件中,LIB文件的长度要小的多,在进行隐式链接DLL时要用到它。读者可能已经注意到在MyDll.h中有关键字"extern C",它可以使其他编程语言访问你编写的DLL中的函数。
LoadRunner调用动态链接库
上面完成动态链接库开发后,下面就介绍动态链接库如何被LoadRunner进行调用,其实也是很简单的。在LoadRunner中的DLL调用有局部调用与全局调用,下面介绍局部调用。
首先把你编译的DLL放在角本路径下面,这里是MyDll.dll,MyDll.lib.然后在Action中使用
lr_load_dll("MYDll.dll"),此函数可以把DLL加载进来,让你调用DLL里面的函数,而DLL中的运算是编译级的,所以效率极高,代码样例如下:
#include "lrs.h"
Action()
{
//
int nRet = 6;
char srckey[129];
memset(srckey, 'a', 128);
lr_message(lr_eval_string(srckey));
lr_load_dll("MyDLL.dll");
nRet = desinit(5,8);
lr_message("比较的结果为%d",nRet);
return 0;
}
运行结果
比较的结果为8
全局的动态链接库的调用则需要修改mdrv.dat,路径在LoadRunner的安装目录下面(LoadRunner/dat directory);在里面修改如例:
[WinSock]
ExtPriorityType=protocol
WINNT_EXT_LIBS=wsrun32.dll
WIN95_EXT_LIBS=wsrun32.dll
LINUX_EXT_LIBS=liblrs.so
SOLARIS_EXT_LIBS=liblrs.so
HPUX_EXT_LIBS=liblrs.sl
AIX_EXT_LIBS=liblrs.so
LibCfgFunc=winsock_exten_conf
UtilityExt=lrun_api
ExtMessageQueue=0
ExtCmdLineOverwrite=-WinInet No
ExtCmdLineConc=-UsingWinInet No
WINNT_DLLS=user_dll1.dll, user_dll2.dll, ...
//最后一行是加载你需要的DLL
这样你就可以在LR中随意的调用程序员写的API函数,进行一些复杂的数据加密,准备的一些操作,进行复杂的测试。同时如果你觉的有大量高复杂的运算也可以放在DLL中进行封装,以提高效率。
作者:
bzcyer
时间:
2011-3-1 15:00
补充一点,在VS2003下建标准DLL,可以这样:
文件-新建-项目-Win32-Win32项目,然后Next,在应用程序设置处,勾上“DLL”
今天刚好在DLL里简单的写了个add(),然后用lR做了个加法。
作者:
wentyfong
时间:
2013-3-28 18:31
LZ帖子不给力,勉强给回复下吧
作者:
ReerieBog
时间:
2013-4-11 16:02
向楼主学习
作者:
夜蔓
时间:
2014-4-9 21:33
确实不错,顶先
作者:
淡淡旳微笑╮
时间:
2014-4-13 16:48
看了LZ的帖子,我只想说一句很好很强大!
作者:
弃忆投明。
时间:
2014-5-18 19:32
顶不错 支持下
作者:
那些明媚阳光ゝ
时间:
2014-6-13 09:55
其实,很多情况下都是这样的,习惯就好。
作者:
小榔头
时间:
2014-6-30 17:43
还不错哦,如果再能多分享一些就perfect了!
作者:
微凉离别意°
时间:
2014-10-14 21:09
路过的帮顶
作者:
坐看云起时
时间:
2014-10-26 10:16
顶不错 支持下
作者:
溺海°
时间:
2014-10-30 16:09
顶不错 支持下
作者:
≈烟波流传
时间:
2014-11-18 14:57
very good.
作者:
冷眸ゞ
时间:
2014-11-26 11:38
确实不错,顶先
作者:
望树
时间:
2015-1-26 10:27
我了个去,顶了
作者:
喘生@
时间:
2015-2-23 11:19
鼎力支持!!
作者:
道拉格斯
时间:
2015-7-27 09:33
这么强,支持楼主,佩服
作者:
阿Q精神
时间:
2015-9-11 12:22
路过 帮顶 嘿嘿
作者:
海沫深@
时间:
2015-9-11 21:12
不错 支持一个了
作者:
O丶ne丨柒夜彡
时间:
2015-9-21 09:41
very good.
作者:
活出高姿态、
时间:
2016-1-20 12:01
很有借鉴意义,先收藏了,谢谢楼主。
作者:
别低头
时间:
2016-3-1 10:02
有空一起交流一下。
作者:
夏木
时间:
2016-4-11 10:22
其实,很多情况下都是这样的,习惯就好。
作者:
七度光
时间:
2016-5-17 12:23
前排支持下了哦~
作者:
清故宸凉
时间:
2016-7-9 13:32
打酱油的人拉,顺便赚点金币
作者:
北船余音
时间:
2016-7-14 19:58
前排支持下了哦~
作者:
CHEN沦
时间:
2016-10-8 17:57
确实不错,顶先
作者:
致命朱丽叶
时间:
2016-11-23 21:23
打酱油的人拉,顺便赚点金币
作者:
红铃铛
时间:
2016-12-21 11:54
很有借鉴意义,先收藏了,谢谢楼主。
作者:
寻她人
时间:
2017-3-7 17:02
非常好,顶一下占位编辑
作者:
童年勾勒了
时间:
2017-6-14 17:20
以我的经验来看,楼主的想法是可以执行的~
作者:
不成功也成仁
时间:
2017-9-6 18:24
打酱油的人拉,顺便赚点金币
作者:
彼岸蔷薇
时间:
2017-9-20 21:36
我了个去,顶了
作者:
龟兔
时间:
2017-9-26 20:39
确实不错,顶先
作者:
入花庭
时间:
2017-11-3 07:18
very good.
作者:
班尼路
时间:
2017-12-6 15:00
确实不错,顶先
作者:
魅╰美。
时间:
2017-12-8 10:55
不错 支持一个了
作者:
令狐帅帅
时间:
2017-12-10 17:44
看起来不错
作者:
BABY衣
时间:
2018-1-5 13:59
其实,很多情况下都是这样的,习惯就好。
作者:
孤岛
时间:
2018-3-22 20:43
很有借鉴意义,先收藏了,谢谢楼主。
作者:
永远的蔷薇
时间:
2018-4-23 15:03
好帖是需要鼓励的~
作者:
六角星
时间:
2018-7-3 12:01
很有借鉴意义,先收藏了,谢谢楼主。
作者:
我要专一了
时间:
2018-11-5 07:29
非常好,顶一下占位编辑
作者:
掐死时间
时间:
2018-11-27 20:36
前排支持下了哦~
作者:
瑹歌
时间:
2018-12-3 08:58
没人回帖。。。我来个吧!
作者:
画子入戏.
时间:
2019-2-28 19:05
打酱油的人拉,顺便赚点金币
作者:
寵柳嬌花
时间:
2019-6-10 07:08
我也来顶一下..
作者:
唱片
时间:
2019-6-10 14:23
非常好,顶一下占位编辑
作者:
黄的笔记
时间:
2019-7-26 17:07
支持,赞一个
作者:
微凉之夏。
时间:
2019-8-2 15:43
很有见地的探讨,先收藏着~
作者:
海内比邻
时间:
2019-8-4 21:52
向楼主学习
作者:
愿out¨
时间:
2019-11-14 15:25
这么强,支持楼主,佩服
作者:
‘黑白交錯℡
时间:
2020-1-13 20:09
这么强,支持楼主,佩服
作者:
顾痣
时间:
2020-1-17 11:01
路过 帮顶 嘿嘿
作者:
倒霉催的
时间:
2020-3-12 13:44
很有借鉴意义,先收藏了,谢谢楼主。
作者:
四叶星光
时间:
2020-6-29 14:40
很有借鉴意义,先收藏了,谢谢楼主。
欢迎光临 思步网 (http://www.step365.com/)
Powered by Discuz! X3.2