你是不是以为第一个程序要快,因为它看着简单而且不用调用API(调用API需要额外的处理VB文档明确指絀大量调用API将降低程序性能)。但事实上在VB集成环境中运行,程序二要比程序一快四分之一;而编译成本机代码或p-code程序二基本上要比程序一快一倍。下面是两个excel函数公式大全在编译成本机代码后运行不同次数所花时间的比较:
的确,调用API是需要额外指令来处理但是甴于使用了指针技术,它没有进行临时字串的分配和拷贝因此速度提高了不少。
怎么样想不到吧!C/C++程序员那么依赖指针,无非也是因為使用指针往往能更直接的去处理问题的根源更有驾驭一切的快感。他们不是不知道使用指针的危险他们不是不愿意开卫星定位无级變速的汽车,只是骑摩托更有快感而有些地方只有摩托才走得过去。
和在C里类似在VB里我们使用指针也不过三个理由:
一是效率,这是┅种态度一种追求在VB里也一样;
二是不能不用,因为操作系统是C写的它时刻都在提醒我们它需要指针;
三是突破限制,VB想照料我们的┅切VB给了我们很强的类型检查,VB象我们老妈一样对我们关心到有时我们会受不了,想偶尔不听妈妈的话吗你需要指针!
但由于缺少官方的技术支持,在VB里指针变得很神秘。因此在C里一些基本的技术在VB里就变得比较困难。本文的目的就是要提供给大家一种简单的方法来将C处理指针的技术拿到VB里来,并告诉你什么是可行的什么可行但必须要小心的,什么是可能但不可行的什么是根本就不可能的。
是的程序二基本上就已经让我们看到VB指针技术的模样了。总结一下在VB里用指针技术我们需要掌握三样东西:CopyMemory,VarPtr/StrPtr/ObjPtr,
里没有这几个excel函数公式大全但只要还能调用API,我们就可以试试上面的几个声明这样在中没有VarPtr,我们可以用声明API的方式来引入MSVBVM60.DLL中的VarPtr现在的问题如果不用VB的運行时DLL文件,你能不能自己实现一个ObjPtr答案在下一节后给出。
如果以一个老师的身份来说话我会说:最好永远也不要用Any!是的,我没说錯是永远!所以我没有把它放在程咬金的三板斧里。当然这个问题和是不是应该使用指针这个问题一样会引发一场没有结果的讨论,峩告诉你的只是一个观点因为有时我们会为了效率上的一点点提高或想偷一点点懒而去用Any,但这样做需要要承担风险
Any不是一个真正的類型,它只是告诉VB编译器放弃对参数类型的检查这样,理论上我们可以将任何类型传递给API。
Visual Basic 声明"这一节文档里告诉我们,只有C的声奣为LPVOID和NULL时我们才用Any。实际上如果你愿意承担风险所有的类型你都可以用Any。当然也可以如我所说,永远不要用Any
为什么要这样?那为什么VB官方还要提供Any是信我的,还是信VB官方的有什么道理不用Any?
如前面所说VB官方不鼓励我们使用指针。因为VB所标榜的优点之一就是沒有危险的指针操作,所以的内存访问都是受VB运行时库控制的在这一点上,JAVA语言也有着同样的标榜但是,同JAVA一样VB要避免使用指针而嘚到更高的安全性,就必须要克服没有指针而带来的问题VB已经尽最大的努力来使我们远离指针的同时拥有强类型检查带来的安全性。但昰操作系统是C写的里面到处都需要指针,有些指针是没有类型的就是C程序员常说的可怕的void*无类型指针。它没有类型因此它可以表示所有类型。如CopyMemory所对应的是C语言的memcpy它的声明如下:
因memcpy前两个参数用的是void*,因此任何类型的参数都可以传递给他
一个用C的程序员,应该知噵在Cexcel函数公式大全库里这样的void*并不少见也应该知道它有多危险。无论传递什么类型的变量指针给上面memcpy的void*C编译器都不会报错或给任何警告。
在VB里大多数时候我们使用Any就是为了使用void*,和在C里一样VB也不对Any进行类型检查,我们也可以传递任何类型给AnyVB编译器也都不会报错或給任何警告。
但程序运行时会不会出错就要看使用它时是不是小心了。正因为在C里很多错误是和void*相关的所以,C++鼓励我们使用satic_cast<void*>来明确指絀这种不安全的类型的转换已利于发现错误。
说了这么多C/C++其实我是想告诉所有VB的程序员,在使用Any时我们必须和C/C++程序员使用void*一样要高喥小心。
VB里没有satic_cast这种东西但我们可以在传递指针时明确的使用long类型,并且用VarPtr来取得参数的指针这样至少已经明确地指出我们在使用危險的指针。如程序二经过这样的处理就成了下面的程序:
【程序五】:注释:使用更安全的CopyMemory明确的使用指针!
注意,上面CopyMemory的声明用的昰ByVal和long,要求传递的是32位的地址值当我们将一个别的类型传递给这个API时,编译器会报错比如现在我们用下面的语句:
【程序六】:注释:有点象【程序四】,但将常量40000换成了值为1的变量.