




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
LoadRunner測試SQL語句性能本次通過loadRunner錄制SQLServer介紹一下如何測試一個(gè)sql語句或存儲(chǔ)過程的執(zhí)行性能。主要分如下幾個(gè)步驟完成:第一步、測試準(zhǔn)備第二步、配置ODBC數(shù)據(jù)源第三步、錄制SQL語句在SqlServer查詢分析器中的運(yùn)行過程第四步、優(yōu)化錄制腳本,設(shè)置事務(wù)第五步、改變查詢數(shù)量級(jí)查看SQL語句的性能第六步、在controller中運(yùn)行腳本下面開始具體的介紹:測試準(zhǔn)備階段我們首先要確認(rèn)測試數(shù)據(jù)庫服務(wù)器:我們可以在本地安裝SQLSERVER數(shù)據(jù)庫服務(wù)端及客戶端,也可以確定一臺(tái)裝好的SQLSERVER服務(wù)器。接下來,準(zhǔn)備測試數(shù)據(jù):對數(shù)據(jù)庫測試時(shí)我們要考慮的不是SQL語句是否能夠正確執(zhí)行,而是在某數(shù)量級(jí)的情況下SQL語句的執(zhí)行效率及數(shù)據(jù)庫服務(wù)的運(yùn)行情況,所以我們分別準(zhǔn)備不同數(shù)量級(jí)的測試數(shù)據(jù),即根據(jù)實(shí)際的業(yè)務(wù)情況預(yù)估數(shù)據(jù)庫中的記錄數(shù),在本次講解中我們不考慮業(yè)務(wù)邏輯也不考慮數(shù)據(jù)表之間的關(guān)系,我們只建立一張表,并向此表中加入不同數(shù)量級(jí)的數(shù)據(jù),如分別加入1000條、10000條、50000條、100000條數(shù)據(jù)查看某SQL語句的執(zhí)行效率。在查詢分析器中運(yùn)行如下腳本:--創(chuàng)建測試數(shù)據(jù)庫createdatabaseloadrunner_test;useloadrunnertest--創(chuàng)建測試數(shù)據(jù)表createtabletest_table(usernamevarchar(50),sexint,ageint,addressvarchar(100),postint)--通過一段程序插入不同數(shù)量級(jí)的記錄,具體的語法在這里就不多說了declare@iintset@i=0while@i<1000 /循環(huán)1000次,可以根據(jù)測試數(shù)據(jù)情況改變插入條數(shù)beginBEGINTRANT1insertintotest_table(username,sex,age,address,post)values(戶瑞海'+cast(@iasvarchar),@i—1,@i+1,'北京市和平里'+cast(@iasvarchar)+'號(hào)',123456);IF@@ERROR<>0beginrollback;select@@errorendelsebegincommit;set@i= @i+1endend好了,執(zhí)行完上述語句后,建立的數(shù)據(jù)表中已經(jīng)有1000條記錄了,下面進(jìn)行第二步的操作,配置ODBC數(shù)據(jù)源,為了能讓loadrunner能夠通過ODBC協(xié)議連接到我們建立的SQLSERVER數(shù)據(jù)路,我們需要在本機(jī)上建立ODBC數(shù)據(jù)源,建立方法如下:控制面板一性能和維護(hù)一管理工具一數(shù)據(jù)源(ODBC)--添加,在列表中選擇SQLSERVER點(diǎn)擊完成,根據(jù)向?qū)л斎霐?shù)據(jù)源名稱,鏈接的服務(wù)器,下一步,輸入鏈接數(shù)據(jù)庫的用戶名和密碼,更改鏈接的數(shù)據(jù)庫,完成ODBC的配置,如果配置正確的話,在最后一步點(diǎn)擊“測試數(shù)據(jù)源”,會(huì)彈出測試成功的提示。配置好ODBC數(shù)據(jù)源后就要錄制SQL語句在查詢分析器中的執(zhí)行過程了:1、打開loadrunner,選擇ODBC協(xié)議2、 在startrecording中的勺applicationtype選擇Win32application;programtorecord中錄入SQLSERVER查詢分析器的路徑“..\安裝目錄\isqlw.exe”3、 開始錄制,首先通過查詢分析器登錄SQLSERVER,在打開的查詢分析器窗口中輸入要測試的SQL語句口“select*fromtest_table;”4、 在查詢分析器中執(zhí)行該語句,執(zhí)行完成后,結(jié)束錄制好了,現(xiàn)在就可以看到loadrunner生成的腳本了(由于腳本過長,在這里就不粘貼了,有需要的朋友可以加我QQ,我把腳本發(fā)給你們),通過這些語句,我們可以看出,登錄數(shù)據(jù)庫的過程、執(zhí)行SQL語句的過程。接下來,我們來優(yōu)化腳本,我們分別為數(shù)據(jù)庫登錄部分和執(zhí)行SQL語句的部分加一個(gè)事物,在增加一個(gè)double的變量獲取事務(wù)執(zhí)行時(shí)間,簡單內(nèi)容如下:Action(){doubletrans_time;/定義一個(gè)double型變量用來保存事務(wù)執(zhí)行時(shí)間lr_start_transaction("sqserver_login");/設(shè)置登錄事務(wù)的開始lrd_init(&InitInfo,DBTypeVersion); //初始化鏈接(下面的都是loadrunner生成的腳本了,大家可以通過幫助查到每個(gè)函數(shù)的意思)lrd_open_context(&Ctx1,LRD_DBTYPE_ODBC,0,0,0);lrd_db_option(Ctx1,0T_0DBC_0V_0DBC3,0,0);lrd_alloc_connection(&Con1,LRD_DBTYPE_ODBC,Ctx1,0/*Unused*/,0);trans_time=lr_get_transaction_duration("sqserver_login");//獲得登錄數(shù)據(jù)庫的時(shí)間lr_output_message("sqserver_login事務(wù)耗時(shí)%f秒",trans_time);//輸出該時(shí)間lr_end_transaction("sqserver_login",LR_AUTO);/結(jié)束登錄事務(wù)lr_start_transaction("start_select");//開始查詢事務(wù)lrd_cancel(0,Csr2,0/*Unused*/,0);lrd_stmt(Csr2,"select*fromtest_table;\r\n",-1,1,0/*None*/,0);//此句為執(zhí)行的SQLlrd_bind_cols(Csr2,BCInfo_D42,0);lrdfetch(Csr2,-10, 1, 0,PrintRow24,0);trans_time=lr_get_transaction_duration("start_select");//獲得該SQL的執(zhí)行時(shí)間lr_output_message("start_select事務(wù)耗時(shí)%f秒",trans_time);//輸出該時(shí)間lrendtransaction("startselect",LRAUTO);//結(jié)束查詢事務(wù)優(yōu)化后,在執(zhí)行上述腳本后,就可以得到登錄到數(shù)據(jù)庫的時(shí)間及運(yùn)行select*fromtest_table這條語句的時(shí)間了,當(dāng)然我們也可以根據(jù)實(shí)際情況對該條語句進(jìn)行參數(shù)化,可以測試多條語句的執(zhí)行時(shí)間,也可以將該語句改為調(diào)用存儲(chǔ)過程的語句來測試存儲(chǔ)過程的運(yùn)行時(shí)間。接下來把該腳本在controller中運(yùn)行,設(shè)置虛擬用戶數(shù),設(shè)置集合點(diǎn),這些操作我就不說了,但是值得注意的是,沒有Mercury授權(quán)的SQLSERVER用戶license,在運(yùn)行該腳本時(shí)回扌報(bào)錯(cuò),提示“YoudonothavealicenseforthisVusertype.PleasecontactMercuryInteractivetorenewyourlicense”我們公司窮啊買不起loadrunner,所以我也無法繼續(xù)試驗(yàn),希望有l(wèi)icense朋友們監(jiān)控一下運(yùn)行結(jié)果!最起碼在VUGen中運(yùn)行該腳本我們可以得到任意一個(gè)SQL語句及存儲(chǔ)過程的執(zhí)行時(shí)間,如果我們測試的B/S結(jié)構(gòu)的程序,我們也可以通過HTML協(xié)議錄制的腳本在CONTROLLER中監(jiān)控SQLSERVER服務(wù)器的性能情況,這樣兩方面結(jié)合起來就可以對數(shù)據(jù)庫性能做一個(gè)完整的監(jiān)控了。本人對LOADRUNNER也是在摸索中,如果文章有寫的不對,或理解錯(cuò)誤的地方請指出,不甚感激。(以上言論僅代表作者的個(gè)人觀點(diǎn),不代表51Testing觀點(diǎn))/*需要的表結(jié)構(gòu)如下CREATETABLE'test_data'('order_id'BIGINTUNSIGNEDNOTNULLCOMMENT'Ordernumbers.Mustbeunique.','status'BOOLNOTNULLDEFAULT'O'COMMENT'Whetherdatahasbeenusedornot.Avalueof0meansFALSE.',、date_used'DATETIMENULLCOMMENT'Date/timethatthedatawasused.',UNIQUE('order_id'))ENGINE=innodbCOMMENT='LoadRunnertestdata';*/Action(){intrc;intdb_connection;//數(shù)據(jù)庫連接intquery_result;//查詢結(jié)果集MYSQL_RESchar**result_row;//查詢的數(shù)據(jù)衕char*server="localhost";char*user="root";char*password="123456";char*database="test";intport=3306;intunix_socket=NULL;intflags=0;//找到libmysql.dll的所在位置.rc=lr_load_dll("C:\\ProgramFiles\\MySQL\\MySQLServer5.1WbinWlibmysql.dll");if(rc!=0){lr_error_message("Couldnotloadlibmysql.dll");lr_abort();}//創(chuàng)建MySQL對象db_connection=mysql_init(NULL);if(db_connection==NULL){lr_error_message("Insufficientmemory");lr_abort();}//連接到MySQL數(shù)據(jù)庫rc=mysql_real_connect(db_connection,server,user,password,database,port,unix_socket,flags);if(rc==NULL){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}//向數(shù)據(jù)庫插入數(shù)據(jù)//此處的{ORDER_ID}是一個(gè)參數(shù),簡單測試時(shí)可以用一個(gè)常數(shù)代替lr_save_string(lr_eval_string("INSERTINTOtest_data(order_id)VALUES({ORDER_ID})"),"paramInsertQuery");rc=mysql_query(db_connection,lr_eval_string("{paramInsertQuery}"));if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}//從數(shù)據(jù)庫讀取一個(gè)數(shù)據(jù)并顯示rc=mysql_query(db_connection,"SELECTorder_idFROMtest_dataWHEREstatusISFALSELIMIT1");if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}query_result=mysql_use_result(db_connection);if(query_result==NULL){lr_error_message("%s",mysql_error(db_connection));mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}//如果結(jié)果集包含多行數(shù)據(jù),需要多次調(diào)用mysql_fetch_row直到返回NULLresult_row=(char**)mysql_fetch_row(query_result);if(result_row==NULL){lr_error_message("Didnotexpecttheresultsettobeempty");mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}//保存參數(shù),用于刪除這行數(shù)據(jù)lr_save_string(result_row[O],"paramOrderlD");lr_output_message("OrderIDis:%s",lr_eval_string("{paramOrderID}"));mysql_free_result(query_result);//在事務(wù)里更新一行數(shù)據(jù),需要用InnoDB引擎rc=mysql_query(db_connection,"BEGIN");//啟動(dòng)事務(wù)if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}//使用"FORUPDATE"鎖住要更新的數(shù)據(jù)行rc=mysql_query(db_connection,"SELECTorder_idFROMtest_dataWHEREstatusISFALSELIMIT1FORUPDATE");if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}query_result=mysql_use_result(db_connection);if(query_result==NULL){lr_error_message("%s",mysql_error(db_connection));mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}result_row=(char**)mysql_fetch_row(query_result);if(result_row==NULL){lr_error_message("沒有查詢到結(jié)果");mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}lr_save_string(result_row[O],"paramOrderID");lr_output_message("OrderIDis:%s",lr_eval_string("{paramOrderID}"));mysql_free_result(query_result);lr_save_string(lr_eval_string("UPDATEtest_dataSETstatus=TRUE,date_used=NOW()WHEREorder_id='{paramOrderID}'"),"paramUpdateQuery");rc=mysql_query(db_connection,lr_eval_string("{paramUpdateQuery}"));if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}rc=mysql_query(db_connection,"COMMIT");//提交事務(wù)if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}//再次查找數(shù)據(jù),應(yīng)該為空了,因?yàn)榍懊娴氖聞?wù)更新了標(biāo)志rc=mysql_query(db_connection,"SELECTorder_idFROMtest_dataWHEREstatusISFALSELIMIT1");if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}query_result=mysql_use_result(db_connection);if(query_result==NULL){lr_error_message("%s",mysql_error(db_connection));mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}result_row=(char**)mysql_fetch_row(query_result);if(result_row==NULL){lr_output_message("Resultsetisemptyasexpected");mysql_free_result(query_result);}else{lr_error_message("Didnotexpecttheresultsettocontainanyrows");mysql_free_result(query_result);mysql_close(db_connection);lr_abort();}//刪除數(shù)據(jù)lr_save_string(lr_eval_string("DELETEFROMtest_dataWHEREorder_id='{paramOrderID}'"),"paramDeleteQuery");rc=mysql_query(db_connection,lr_eval_string("{paramDeleteQuery}"));if(rc!=0){lr_error_message("%s",mysql_error(db_connection));mysql_close(db_connection);lr_abort();}//釋放MySQL資源mysql_close(db_connection);return0;}本文章來源于西盟軟件站【/r/】詳細(xì)地址:/article/175/data/2009/2009070819880.html(轉(zhuǎn))LoadRunner測試過程中調(diào)用dll文件的制作與使用上一篇/下一篇2009-01-1716:35:36/個(gè)人分類:LoadRunner查看(109)/評(píng)論(0)/評(píng)分(0/0)在Windows操作系統(tǒng)中使用DLL有很多優(yōu)點(diǎn),最主要的一點(diǎn)是多個(gè)應(yīng)用程序、甚至是不同語言編寫的應(yīng)用程序可以共享一個(gè)DLL文件,真正實(shí)現(xiàn)了資源"共享”,大大縮小了應(yīng)用程序的執(zhí)行代碼,更加有效的利用了內(nèi)存;使用DLL的另一個(gè)優(yōu)點(diǎn)是DLL文件作為一個(gè)單獨(dú)的程序模塊,封裝性、獨(dú)立性好,在軟件需要升級(jí)的時(shí)候,開發(fā)人員只需要修改相應(yīng)的DLL文件就可以了,而且,當(dāng)DLL中的函數(shù)改變后,只要不是參數(shù)的改變,程序代碼并不需要重新編譯。這在編程時(shí)十分有用,大大提高了軟件開發(fā)和維護(hù)的效率。在LR下也可以直接調(diào)用動(dòng)態(tài)鏈接庫文件,針對一些使用LR腳本編寫比較煩瑣的方法可以考慮此方法(比如各種加解密算法的實(shí)現(xiàn),數(shù)據(jù)庫的操作等),并能夠使測試腳本簡單明了。鑒于此,本人初次嘗試了如何制作DLL文件并在LR中使用。1、dll文件的制作在VisualC++6.0開發(fā)環(huán)境下,打開File-New-Project選項(xiàng),可以選擇Win32Dynamic-LinkLibrary來創(chuàng)建一個(gè)名為dllfortest的空的dll工程(這只是方法之一)。在該項(xiàng)目中新建一個(gè)dllfortest.h和dllfortest.cpp文件,文件的內(nèi)容如下://dllfortest.hextern"C"_declspec(dllexport)intMax(inta,intb,intc);extern"C"_declspec(dllexport)intMin(inta,intb,intc);//dllfortest.cpp包含一個(gè)計(jì)算三個(gè)整數(shù)中最大值和最小值的方法#include"dllfortest.h"intMax(inta,intb,intc)intRes;Res=(a>b?a:b)>c?(a>b?a:b):c;returnRes;}intMin(inta,intb,intc){intRes;Res=(a>b?b:a)>c?c:(a>b?b:a);returnRes;}該動(dòng)態(tài)鏈接庫編譯成功后,打開dllfortest工程目錄下的debug目錄下,可以看到生成了一個(gè)dllfortest.dll文件,這就是我們想要的文件。2、dll文件在LR中的調(diào)用打開LRVUGenerator,選擇CVuser協(xié)議(或其他支持C的協(xié)議),進(jìn)入編輯界面。Action部分如下所示:Action(){lr_load_dll("dllfortest.dll");lr_message("MaxResultis%d",Max(100,200,67));lr_message("MinResultis%d",Min(55,97,63));return0;}將dllfortest.dll文件復(fù)制到腳本所在的目錄(如果不復(fù)制的話,lr_load_dll的參數(shù)應(yīng)該寫成dll文件的絕對路徑),如果編譯沒有報(bào)錯(cuò)的話,就可以直接運(yùn)行了。運(yùn)行結(jié)果如下:VirtualUserscrptstartedStartingactionvuser_init.Endingactionvuser_init.RunningVuser...Startingiteration1.StartingactionAction.MaxResultis200MinResultis55EndingactionAction.Endingiteration1.EndingVuser...Startingactionvuser_end.Endingactionvuser_end.VuserTerminated.如果在腳本中用到了DLL文件中并不存在的方法名時(shí),編譯也能通過,但是運(yùn)行時(shí)LR會(huì)報(bào)錯(cuò),提示不存在該方法比如我們在腳本中添加一句:lr_message("MinResultis%d",Sum(55,97,63));//Sum方法并不存在運(yùn)行時(shí)錯(cuò)誤信息如下:Action.c(7):Error:Cinterpreterruntimeerror:Action.c(7):Error--Unresolvedsymbol:Sum.Action.c(7):Notify:CCItrace:Compiled_code(0):Action()這個(gè)例子并沒有體現(xiàn)出DLL文件調(diào)用的優(yōu)點(diǎn),因?yàn)檎{(diào)用的方法在LR中用C直接就可以完成,但涉及到LR中完不成的任務(wù)時(shí),或許dll文件的作用就體現(xiàn)出來了example:LoadRunner提供了功能強(qiáng)大的API集合,足夠應(yīng)付大多數(shù)性能測試的需求。但在某些情況下,這些API仍然有覆蓋不到的地方。例如,我們有一個(gè)WEB應(yīng)用,該應(yīng)用有一個(gè)頁面輸入用戶的信息,為了安全起見,用戶輸入的信息在提交之前都要先進(jìn)行加密處理,加密處理通過本地的COM組件實(shí)現(xiàn)。對這個(gè)要求而言,LoadRunner的現(xiàn)有API不能提供直接支持,因?yàn)長oadRunner在錄制腳本時(shí)只錄制數(shù)據(jù)交互,因此,COM的加密處理過程是不能錄制下來的。在LoadRunner的腳本中,可能只有類似以下的語句描述了這個(gè)過程:web_url("userinfo","URL=http://testweb/userinfo.aspx","TargetFrame=","Resource=0","Referer=",LAST);web_submit_form("login","Snapshot=t4.inf",ITEMDATA,"Name=username","Value=4e92Sh6d394g",ENDITEM,"Name=password","Value=932A2hf34U18",ENDITEM,LAST);從腳本可以看到,輸入的數(shù)據(jù)是加密后的數(shù)據(jù),但LR沒有錄制到加密過程。假設(shè)加密函數(shù)所在的DLL名為security.dll,用于加密的函數(shù)名為encode,則一種可能的對腳本的修改方法如下代碼所示。char*encode_username,*encode_password,*orgin_username,*orgin_password;char*uservalue,passvalue;intret;web_url("userinfo","URL=http://testweb/userinfo.aspx","TargetFrame=","Resource=0","Referer=",LAST);orgin_username=lr_eval_string(“{username}”);〃獲取參數(shù)的值orgin_password=lr_eval_string(“{password}”);ret=lr_load_dll(“security.dll”); 〃加載DLL庫encode(origin_username,encode_username);〃調(diào)用encode函數(shù)encode(origin_password,encode_password);sprintf(uservalue,“Value=%s”,encode_username);sprintf(passvalue,“value=%s”,encode_password);web_submit_form("login","Snapshot=t4.inf",ITEMDATA,"Name=username",uservalue,ENDITEM,"Name=password",passvalue,ENDITEM,LAST);注意:有些腳本錄制需要相應(yīng)的patch的支持,如錄制DotNet編寫的應(yīng)用程序你需要把lr78安裝盤\Patches\Trap_for_.net_patch文件夾中trpfnc32.32dll拷貝到loadrunner'bin路徑下,才能正常工作。[轉(zhuǎn)貼]LoadRunner下DLL的調(diào)用場景介紹最近在做類似于QQ的通信工具的性能測試時(shí)發(fā)現(xiàn)了一些問題,現(xiàn)總結(jié)出來與大家分享一下。希望大家在使用LoadRunner時(shí)不僅僅停在只是錄制/播放腳本,而全面提升腳本的編程技術(shù),解決復(fù)雜場景。本次測試中碰到的問題是這樣的,在消息的傳送過程中遇到了DEC加密的過程,LoadRunner錄制到的全是加密的消息,比如我錄制了某一個(gè)用戶的登陸,發(fā)送消息,退出,但由于是加密的,只能單個(gè)用戶使用,但如果我想并發(fā)多少個(gè)用戶就存在很多問題,最直接的一個(gè)問題就是用戶名是加密的,密碼是加密的,當(dāng)然你可以說讓程序那里注掉加密的代碼進(jìn)行明碼的測試,當(dāng)然也是一種辦法。但程序組提出了要使用更真實(shí)的方法來模擬,這時(shí)就必需使用下面介紹的方法。一開始是直接把API移植到LoadRunner中來,不過由于加密算法異常復(fù)雜,有幾層循環(huán),而腳本是解釋執(zhí)行的,進(jìn)行一次加密運(yùn)算可能需要好幾分鐘,當(dāng)然在腳本里可以把腳本本身運(yùn)行的時(shí)間去掉,但這樣做顯然沒有直接調(diào)用DLL來的效率高。由于程序組比較忙,所以無法提供DLL給測試,所以測試組完成了DLL的編寫,并在LoadRunner中調(diào)用成功,高效的完成了用戶信息加密,參數(shù)關(guān)聯(lián),成功的完成了測試。動(dòng)態(tài)鏈接庫的編寫在VisualC++6.0開發(fā)環(huán)境下,打開FileNewProject選項(xiàng),可以選擇Win32DynamicLinkLibrary建立一個(gè)空的DLL工程。Win32Dynamic-LinkLibrary方式創(chuàng)建Non-MFCDLL動(dòng)態(tài)鏈接庫每一個(gè)DLL必須有一個(gè)入口點(diǎn),這就象我們用C編寫的應(yīng)用程序一樣,必須有一個(gè)WINMAIN函數(shù)一樣。在Non-MFCDLL中DllMain是一個(gè)缺省的入口函數(shù),你不需要編寫自己的DLL入口函數(shù),用這個(gè)缺省的入口函數(shù)就能使動(dòng)態(tài)鏈接庫被調(diào)用時(shí)得到正確的初始化。如果應(yīng)用程序的DLL需要分配額外的內(nèi)存或資源時(shí),或者說需要對每個(gè)進(jìn)程或線程初始化和清除操作時(shí),需要在相應(yīng)的DLL工程的.CPP文件中對DIIMain()函數(shù)按照下面的格式書寫。BOOLAPIENTRYDllMain(HANDLEhModule,DWORDul_reason_for_call丄PVOIDIpReserved){switch(ul_reason_for_call){caseDLL_PROCESS_ATTACH:break;caseDLL_THREAD_ATTACH:break;caseDLL_THREAD_DETACH:break;caseDLL_PROCESS_DETACH:break;default:break;}returnTRUE;}參數(shù)中,hMoudle是動(dòng)態(tài)庫被調(diào)用時(shí)所傳遞來的一個(gè)指向自己的句柄(實(shí)際上,它是指向_DGROUP段的一個(gè)選擇符);ul_reason_for_call是一個(gè)說明動(dòng)態(tài)庫被調(diào)原因的標(biāo)志,當(dāng)進(jìn)程或線程裝入或卸載動(dòng)態(tài)鏈接庫的時(shí)候,操作系統(tǒng)調(diào)用入口函數(shù),并說明動(dòng)態(tài)鏈接庫被調(diào)用的原因,它所有的可能值為:DLL_PROCESS_ATTACH:進(jìn)程被調(diào)用、DLL_THREAD_ATTACH:線程被調(diào)用、DLL_PROCESS_DETACH:進(jìn)程被停止、DLL_THREAD_DETACH:線程被停止;IpReserved為保留參數(shù)。到此為止,DLL的入口函數(shù)已經(jīng)寫了,剩下部分的實(shí)現(xiàn)也不難,你可以在DLL工程中加入你所想要輸出的函數(shù)或變量了。我們已經(jīng)知道DLL是包含若干個(gè)函數(shù)的庫文件,應(yīng)用程序使用DLL中的函數(shù)之前,應(yīng)該先導(dǎo)出這些函數(shù),以便供給應(yīng)用程序使用。要導(dǎo)出這些函數(shù)有兩種方法,一是在定義函數(shù)時(shí)使用導(dǎo)出關(guān)鍵字_declspec(dllexport),另外一種方法是在創(chuàng)建DLL文件時(shí)使用模塊定義文件.Def。需要讀者注意的是在使用第一種方法的時(shí)候,不能使用DEF文件。下面通過兩個(gè)例子來說明如何使用這兩種方法創(chuàng)建DLL文件。1)使用導(dǎo)出函數(shù)關(guān)鍵字_declspec(dllexport)創(chuàng)建MyDll.dll,該動(dòng)態(tài)鏈接庫中有兩個(gè)函數(shù),分別用來實(shí)現(xiàn)得到兩個(gè)數(shù)的最大和最小數(shù)。在MyDll.h和MyDLL.cpp文件中分別輸入如下原代碼://MyDLL.hextern"C"_declspec(dllexport)intdesinit(intmode);extern"C"_declspec(dllexport)voiddesdone(void);extern"C"_declspec(dllexport)voiddes_setkey(char*subkey,char*key);extern"C"_declspec(dllexport)voidendes(char*block,char*subkey);extern"C"_declspec(dllexport)voiddedes(char*block,char*subkey);//MyDll.cpp
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 涂料品牌測試題目及答案
- 園藝師考試文化基礎(chǔ)知識(shí)試題及答案
- 影像招聘面試題及答案大全
- 深化輔導(dǎo)員招聘知識(shí)體系的構(gòu)建試題及答案
- 相交和垂直(教學(xué)設(shè)計(jì))-2024-2025學(xué)年四年級(jí)上冊數(shù)學(xué)北師大版
- 找因數(shù)(教學(xué)設(shè)計(jì))-2024-2025學(xué)年五年級(jí)上冊數(shù)學(xué)北師大版
- 定制花藝服務(wù)的試題及答案
- 文具店(教學(xué)設(shè)計(jì))-2024-2025學(xué)年三年級(jí)上冊數(shù)學(xué)北師大版
- 園藝師考試知識(shí)要點(diǎn)分析試題及答案
- 2024年福建事業(yè)單位考試應(yīng)試策略探討試題及答案
- 高中物理答題卡模板
- 煤礦防滅火細(xì)則
- 白車身測量點(diǎn)設(shè)計(jì)規(guī)范
- 超星爾雅學(xué)習(xí)通《紅色經(jīng)典影片與近現(xiàn)代中國發(fā)展》章節(jié)測試答案
- 智能藥筐介紹
- 2160kn溢洪道雙向門機(jī)安裝使用說明書
- 振動(dòng)篩安裝作業(yè)指導(dǎo)書
- 正弦交流電的-產(chǎn)生
- 執(zhí)行力or創(chuàng)新力,哪個(gè)是員工更應(yīng)具備的素質(zhì)
- 運(yùn)維工程師維護(hù)月報(bào)
- GB/T 622-2006化學(xué)試劑鹽酸
評(píng)論
0/150
提交評(píng)論