LoadRunner: Creating a custom dll

March 18, 2007 – 5:30 pm

Using LoadRunner's lr_load_dll() function, it is possible to roll your own dll's and use custom functions in your LoadRunner scripts. Here's how.

Mercury's support site gives an example, but it doesn't go far enough to tell you how to actually create the dll. Using Eclipse, here is how to easily create your own dll which you can import into your vugen scripts.

1. Download and install Eclipse and the CDT (C/C++ Development Tools) at the Eclipse web site

2. Choose whether you want to create your dll using C or C++. You can use either, but if you use C++, you have to make sure you export the functions properly (see code sample below)

3. Create a new Managed make project

4. Create yourdll.c file

Code Samples

Here is a sample C++ source file with a single function that performs a login, then returns the login cookie.

#include "windows.h"
#include "wininet.h"
#include "strings.h"
#include 

int WINAPI DllMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	return 0;
}

extern "C" __declspec(dllexport) int getLoginCookie(char * cookie, char * webhost)
{
	HINTERNET hINet, hConnection, hData;
	CHAR buffer[2048] ;
	char *headers="Content-Type: application/x-www-form-urlencoded";
	char *postdata="userName=PerformanceEngineer&userPassword=SecretPassword";
	DWORD dwSize = 0;
	BOOL status;
	std::cout << "running wininet_sample" << 	std::endl;
	DWORD dwRead, dwFlags, dwStatus ;
	hINet = InternetOpen("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
	if ( !hINet )
	{
		std::cout << "InternetOpen failed" << std::endl;
		return 0;
	}
	try
	{
		std::cout << "trying to connect" << std::endl;
		hConnection = InternetConnect( hINet, webhost, INTERNET_DEFAULT_HTTPS_PORT, "","", INTERNET_SERVICE_HTTP, 0, 0 );
		if ( !hConnection )
		{
			std::cout << "InternetConnect failed" << std::endl;
			InternetCloseHandle(hINet);
			return 0;
		}
		std::cout << "InternetConnect passed" << std::endl;
		hData = HttpOpenRequest( hConnection, "POST", "/path/to/Logon",NULL, NULL, NULL, (INTERNET_FLAG_SECURE + INTERNET_FLAG_IGNORE_CERT_CN_INVALID + INTERNET_FLAG_IGNORE_CERT_DATE_INVALID + INTERNET_FLAG_NO_AUTO_REDIRECT), 0 );
		if ( !hData )
		{
			std::cout << "HttpOpenRequest failed" << std::endl;
			InternetCloseHandle(hConnection);
			InternetCloseHandle(hINet);
			return 0;
		}
		std::cout << "HttpOpenRequest passed" << std::endl;
		status = HttpSendRequest( hData, (LPCSTR)headers, strlen(headers), (LPVOID)postdata, strlen(postdata) );
		if (status)
		{
			std::cout << "HttpSendRequest passed" << std::endl;
		}
		else
		{
			std::cout << "HttpSendRequest failed" << std::endl;
			std::cout << GetLastError() << std::endl;
			return 0;
		}
		status = HttpQueryInfo(hData,HTTP_QUERY_RAW_HEADERS_CRLF,(LPVOID)headers,&dwSize,NULL);
		if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
		{
			headers = new char[dwSize];
			status = HttpQueryInfo(hData, HTTP_QUERY_SET_COOKIE, (LPVOID)headers, &dwSize, NULL);
			if (status)
			{
				strncpy(cookie,(char *)headers, dwSize);
				std::cout << (char *)headers << std::endl;
			}
			else
			{
				std::cout << GetLastError() << std::endl;
			}
		}
		strcat(cookie, "; domain=");
		strcat(cookie, webhost);
		while( InternetReadFile( hData, buffer, 255, &dwRead ) )
		{
			if ( dwRead == 0 ) return GetLastError();
			buffer[dwRead] = 0;
		}
	}
	catch(…)
	{
		std::cout << "caught exception" << std::endl;
		return 200;
	}
	InternetCloseHandle(hConnection);InternetCloseHandle(hINet);
	InternetCloseHandle(hData);
	std::cout << "passed" << std::endl;
	return 0;
}

Post a Comment