分享
 
 
 

通过使用类型库提高VB调用DLL函数的性能

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

本文始发于水木清华BBS(smth.org),转载请保留有关信息,谢谢!

通过使用类型库提高VB调用DLL函数的性能

RoachCock@smth

mailto:chen3feng@163.com,

chen3fengx@163.com,

chen3fengx@hotmail.com

VB虽然是个很好玩的东西,但是自身功能有限,限制了VB在某些方面的应用.

MS提供了两种两种方式来增强VB的功能,一种是调用COM组件,另一种就是调用Dll函数

说到调用COM,大家都很熟悉,在Project->Reference或者Project->Component

菜单弹出对话框中选择需要的类型库或者ActiveX控件,就可以把它加入Project.

调用Dll函数也很简单,需要使用Declare函数声明先:

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

然后就可以像内部函数一样调用了:

MessageBox Me.hWnd, "hehe", "Test", 0

下面我分析一下在上面的调用过程中,到底发生了什么.

我们知道,VB的字符串是Unicode字符串,每个字符占两个字节,但是翻开WinUser.h

我们可以看到MessageBoxA的真实定义,

WINUSERAPI int WINAPI MessageBoxA(HWND hWnd ,LPCSTR lpText,

LPCSTR lpCaption, UINT uType);

LPCSTR是一个const char *类型,是一个指向单字节ANSI字符串的指针,

把调用这个函数的Project编译成exe,文件,用VC带的depends.exe看到底到如何引用的函数

竟然除了MSVBVM60.dll.什么也没有!

这中间到底发生了什么呢?

通过反汇编跟踪生成的代码可以知道,VB要先调用__vbaStrToAnsi把字符串转化成ANSI字

符串,再把得到的Ansi字符串传给一个内部函数(一般称为DllFunctionCall),这个函数再

真正去调用Dll中的函数

如果函数调用后还要使用传给Dll函数的字符串参数的话(比如GetWindowText什么的),就

更复杂了,VB编译器会调用一个叫做__vbaStrToUnicode的函数,把参数转化成Unicode,再

传递给函数.

也许你会说,MessageBox并不会改变传给它的参数,根本不需要在转换成Unicode.是的,你

知道,我也知道但是VB编译器不知道,声明函数的Declare语句里可没指出参数传递的方向.

也许你会说,我的程序只在WinNT,Win2K,WinXP下运行,他们内部都是用的Unicode字符串

,我直接调用Unicode版本的MessageBoxW不是更好吗?

对不起,由于Win9x只基本完全实现了ANSI函数,而基本没有实现Unicode版本的函数,而W

inNT则两者都实现了.为了照顾Win9x,VB把声明语句中的String都当成ANSI字符串.

//需要Unicode,却依赖于ANSI操作系统,可怜的VB!

由此,我想你已经看到了Declare语句到底在那里影响了效率.好吧.让我们开始新的历程

!

[idl语言和类型库]

类型库对VB程序员来说应该很熟悉了,这里我只简单的介绍一下idl语言.

IDL (Interface Definition Language)是主要用于COM和CORBA的一种接口定义语言,用

来描述各种接口,只是一种描述语言而不是一种编程语言.IDL的风格类似于C.IDL语言不

但可以描述更多的数据类型还可以描述参数的传递方向,因此上面的两个问题都不再是问

题了.

一般使用IDL语言都是为了描述COM接口等.其实IDL也一样可以用于描述全局函数.让我们

看一个例子,

还举那个MessageBox吧

打开VC6,新建一个Utitity Project,名字就叫MyTlb吧

新建一个文本文件,名字还叫MyTlb.idl吧,输入以下内容:

[ // 方括号表示一个idl属性,用来描述一些额外的信息,要和下面的东西连起来看.

uuid("9F7B1BC0-28C6-11d7-8F56-0080C8F0A08C") // 用VC带的GUidgen生成一个新的

GUID,别和我的这个一样哦

]

library MyLib // library说明了一个类型库,MyLib是库的名字

{

[

dllname("user32.dll") file://因为下面的模块描述了函数,所以需要dll库的名字

]

module Test // test是模块的名字

{

[

entry("MessageBoxW") // entry属性表明下面函数的入口,可以是函数的名字或者序号

]

long __stdcall Message(HWND hWnd, [in]LPCWSTR msg, [in]LPCWSTR title, long

flags);

// __stdcall表示函数的调用约定,后面是参数表

// [in]表示参数只传入,[out][in]表示参数只传入,[in,out]表示既传入又传出,类推

// 对于简单的值类型,可以省略,默认就是[in]了

// 再有函数可以接着写

}

}

按F7编译,一个崭新的类型库诞生了! // btw,直接调用midl编译器也可以,不过我觉得很

多人都不喜欢命令行了, :)

把它引入我们的工程,不需要声明直接就可以调用MessageBox了.反汇编代码,可以发现没

有多余的转换.

而且因为明确的指出了参数传递方向,不需要假设参数会被改变,生成的代码会更高效,

避免了DllFunctionCall的开支,更节省时间.

其他函数也可以一样处理,Windows 98 Resource Kit带了一个Win.tlb,包含了常用Wind

ows类型,常量,以及API的定义,非常方便,完全可以摆脱Declared语句的使用.可以在天网

(http://e.pku.edu.cn)搜到.

不过这个tlb是ANSI版本的(WIn98嘛),如果需要Unicode版本的,就得自己写idl文件编译

至于其他不带类型库的的DLL函数,你可以找这上面的例子自己来,函数数目比较多的情况

下完全划的来.

祝各位假期编程愉快!

--

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有