久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

通過使用類型庫提高VB調(diào)用DLL函數(shù)的性能

 quasiceo 2013-12-03

通過使用類型庫提高VB調(diào)用DLL函數(shù)的性能

閱讀:31次   時間:2005-04-30 00:00:00   字體:[ ]

 
本文始發(fā)于水木清華BBS(smth.org),轉(zhuǎn)載請保留有關(guān)信息,謝謝! 


通過使用類型庫提高VB調(diào)用DLL函數(shù)的性能


RoachCock@smth 
mailto:[email protected],
[email protected],
[email protected]
 
VB雖然是個很好玩的東西,但是自身功能有限,限制了VB在某些方面的應(yīng)用.
MS提供了兩種兩種方式來增強VB的功能,一種是調(diào)用COM組件,另一種就是調(diào)用Dll函數(shù)
 
說到調(diào)用COM,大家都很熟悉,在Project->Reference或者Project->Component
菜單彈出對話框中選擇需要的類型庫或者ActiveX控件,就可以把它加入Project.
 
調(diào)用Dll函數(shù)也很簡單,需要使用Declare函數(shù)聲明先:
Declare Function MessageBox Lib "user32" Alias "MessageBoxA" ( _
ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, _
ByVal wType As Long) As Long
 
然后就可以像內(nèi)部函數(shù)一樣調(diào)用了:
MessageBox Me.hWnd, "hehe", "Test", 0
 
下面我分析一下在上面的調(diào)用過程中,到底發(fā)生了什么.
 
我們知道,VB的字符串是Unicode字符串,每個字符占兩個字節(jié),但是翻開WinUser.h
我們可以看到MessageBoxA的真實定義,
WINUSERAPI int WINAPI MessageBoxA(HWND hWnd ,LPCSTR lpText,
 LPCSTR lpCaption, UINT uType);
 
LPCSTR是一個const char *類型,是一個指向單字節(jié)ANSI字符串的指針,
把調(diào)用這個函數(shù)的Project編譯成exe,文件,用VC帶的depends.exe看到底到如何引用的函數(shù)
 
竟然除了MSVBVM60.dll.什么也沒有!
 
這中間到底發(fā)生了什么呢?
 
通過反匯編跟蹤生成的代碼可以知道,VB要先調(diào)用__vbaStrToAnsi把字符串轉(zhuǎn)化成ANSI字
符串,再把得到的Ansi字符串傳給一個內(nèi)部函數(shù)(一般稱為DllFunctionCall),這個函數(shù)再
真正去調(diào)用Dll中的函數(shù)
 
如果函數(shù)調(diào)用后還要使用傳給Dll函數(shù)的字符串參數(shù)的話(比如GetWindowText什么的),就
更復(fù)雜了,VB編譯器會調(diào)用一個叫做__vbaStrToUnicode的函數(shù),把參數(shù)轉(zhuǎn)化成Unicode,再
傳遞給函數(shù).
 
也許你會說,MessageBox并不會改變傳給它的參數(shù),根本不需要在轉(zhuǎn)換成Unicode.是的,你
知道,我也知道但是VB編譯器不知道,聲明函數(shù)的Declare語句里可沒指出參數(shù)傳遞的方向.
 
也許你會說,我的程序只在WinNT,Win2K,WinXP下運行,他們內(nèi)部都是用的Unicode字符串
,我直接調(diào)用Unicode版本的MessageBoxW不是更好嗎?
 
對不起,由于Win9x只基本完全實現(xiàn)了ANSI函數(shù),而基本沒有實現(xiàn)Unicode版本的函數(shù),而W
inNT則兩者都實現(xiàn)了.為了照顧Win9x,VB把聲明語句中的String都當成ANSI字符串.
//需要Unicode,卻依賴于ANSI操作系統(tǒng),可憐的VB!
 
由此,我想你已經(jīng)看到了Declare語句到底在那里影響了效率.好吧.讓我們開始新的歷程
!
 
[idl語言和類型庫]
類型庫對VB程序員來說應(yīng)該很熟悉了,這里我只簡單的介紹一下idl語言.
IDL (Interface Definition Language)是主要用于COM和CORBA的一種接口定義語言,用
來描述各種接口,只是一種描述語言而不是一種編程語言.IDL的風格類似于C.IDL語言不
但可以描述更多的數(shù)據(jù)類型還可以描述參數(shù)的傳遞方向,因此上面的兩個問題都不再是問
題了.
 
一般使用IDL語言都是為了描述COM接口等.其實IDL也一樣可以用于描述全局函數(shù).讓我們
看一個例子,
 
還舉那個MessageBox吧
 
打開VC6,新建一個Utitity Project,名字就叫MyTlb吧
新建一個文本文件,名字還叫MyTlb.idl吧,輸入以下內(nèi)容:
 
[ // 方括號表示一個idl屬性,用來描述一些額外的信息,要和下面的東西連起來看.
 uuid("9F7B1BC0-28C6-11d7-8F56-0080C8F0A08C") // 用VC帶的GUidgen生成一個新的
GUID,別和我的這個一樣哦
]
library MyLib // library說明了一個類型庫,MyLib是庫的名字
{
 
 [
  dllname("user32.dll") file://因為下面的模塊描述了函數(shù),所以需要dll庫的名字
 ]
 module Test // test是模塊的名字
 {
  [
   entry("MessageBoxW") // entry屬性表明下面函數(shù)的入口,可以是函數(shù)的名字或者序號
  ]
  long __stdcall Message(HWND hWnd, [in]LPCWSTR msg, [in]LPCWSTR title, long
 flags);
  // __stdcall表示函數(shù)的調(diào)用約定,后面是參數(shù)表
  // [in]表示參數(shù)只傳入,[out][in]表示參數(shù)只傳入,[in,out]表示既傳入又傳出,類推
 
  // 對于簡單的值類型,可以省略,默認就是[in]了
  // 再有函數(shù)可以接著寫
 }
}
 
按F7編譯,一個嶄新的類型庫誕生了! // btw,直接調(diào)用midl編譯器也可以,不過我覺得很
多人都不喜歡命令行了, :)
 
把它引入我們的工程,不需要聲明直接就可以調(diào)用MessageBox了.反匯編代碼,可以發(fā)現(xiàn)沒
有多余的轉(zhuǎn)換.
 
而且因為明確的指出了參數(shù)傳遞方向,不需要假設(shè)參數(shù)會被改變,生成的代碼會更高效,
避免了DllFunctionCall的開支,更節(jié)省時間.

 
其他函數(shù)也可以一樣處理,Windows 98 Resource Kit帶了一個Win.tlb,包含了常用Wind
ows類型,常量,以及API的定義,非常方便,完全可以擺脫Declared語句的使用.可以在天網(wǎng)
(http://e.pku.edu.cn)搜到.
 
不過這個tlb是ANSI版本的(WIn98嘛),如果需要Unicode版本的,就得自己寫idl文件編譯

 
至于其他不帶類型庫的的DLL函數(shù),你可以找這上面的例子自己來,函數(shù)數(shù)目比較多的情況
下完全劃的來.
 
祝各位假期編程愉快!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多