大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> 程序开发 -> 在VB中调用动态连接库

在VB中调用动态连接库

时间: 2021-07-31 作者:daque

动作一种大略易用的windows开拓情况,visual basic从一推出就遭到了宏大编制程序职员的欢送。它使 步调员不用再径直面临纷复杂杂的windows动静,而不妨将精神重要会合在步调功效的实行上,大大普及了编制程序功效。凡是事利于必有弊。vb中莫大的封装和模块化减少了编制程序者的承担,同声也使开拓职员遗失了很多考察低层api因变量和径直与windows交互的时机。所以,比拟而言,vb运用步调的实行功效和功效比c/c++或delphi天生的步调要差。为领会决这个题目,在一个巨型的vb开拓运用中,径直挪用windows api因变量简直是不行制止的;同声,再有大概需 要步调员本人用c/c++等开拓少许动静贯穿库,用来在vb中挪用。正文重要计划在32位开拓环 境visual basic 5.0市直接挪用windows 95 api因变量或用户天生的32位动静贯穿库的本领 与准则。  windows动静贯穿库是包括数据和因变量的模块,不妨被其它可实行文献(exe、dll、ocx 等)挪用。动静贯穿库包括两种因变量:输入(exported)因变量和里面(internal)因变量。输入因变量不妨被其它模块挪用,而里面因变量则只能在动静贯穿库里面运用。纵然动静贯穿库也能输入 数据,但本质上它的数据常常是只在里面运用的。运用动静贯穿库的便宜是不言而喻的。将应 用步调的一局部功效索取出来做出动静贯穿库,不只减小了主运用步调的巨细,普及了步调 运转功效,还使它越发容易晋级。多个运用步调共享一个动静贯穿库还能灵验地俭朴体例资 源。正由于如许,在windows体例中,动静贯穿库获得了洪量的运用。  普遍来说,动静贯穿库都是以dll为扩充名的文献,如kernel32.dll、commdlg.dll等。但也有不同,如16位windows的中心元件之一gdi.exe本来也是一个动静库。编写动静贯穿库的东西很多,如visualc++、borlandc++、delphi等,简直本领不妨拜见关系文书档案。底下只以visual c++5.0为例,引见一下开拓运用于visualbasic5.0的动静贯穿库时应提防的题目(正文中一切波及c/c++谈话或编写翻译情况的场合,都以vc5为例;一切波及visualbasic的场合都以vb5 为例)。  动作一种32位windows运用步调的开拓东西,vb5天生的exe文献天然也都是32位的,常常情景下也只能挪用32位的动静贯穿库。然而,并不是一切的32位动静库都能被vb天生的exe 文献精确地辨别。普遍来说,本人编写用来vb运用步调挪用的动静贯穿库时,应提防以次几个上面的题目:  1、天生动静库时要运用__stdcall挪用商定,而不许运用缺省的__cdecl挪用商定;__stdcall 商定常常用来32位api因变量的挪用。  2、在vc第5中学的设置文献(.def)中,必需列出输入因变量的因变量名,以强迫vc5体例将输入因变量的化妆名(decoratedname)改成普遍因变量名;所谓化妆名是vc的编写翻译器在编写翻译进程中天生的输入因变量名,它包括了用户设置的因变量名、因变量参数及因变量地方的类等多上面的消息。因为在vc第5中学设置文献不是必定的,所以工程不包括设置文献时vc5就按本人的商定将用户设置的输入因变量名窜改成化妆名后放到输入因变量列表中,如许的输入因变量在vb天生的运用步调中是不许精确挪用的(只有证明时运用alias子句)。所以须要减少一个.def文献,个中列出用户须要的因变量名,以强迫vc5不按化妆名举行输入。  3、vc第5中学的编写翻译选项"结形成员对齐办法(structure member alignment)" 应设成4字节,其因为将在后文精细引见。  4、因为在c中整型变量是4个字节,而vb中的整型变量仍旧惟有2个字节,所以在c中声 明的整型(int)变量在vb中挪用时要证明为长整型(long),而c中的短整型(short)在vb中则 要证明成整型(integer);下指针对最常用的c谈话数据典型列出了与之等价的visual basic 典型(用来32位本子的windows)。c谈话数据典型在visualbasic中证明为挪用时运用的表白式   atom byval variable as integer 截止为integer 典型的表白式   bool byval variable as long 截止为 long 典型的表白式   byte byval variable as byte 截止为 byte 典型的表白式   char byval variable as byte 截止为 byte 典型的表白式   colorref byval variable as long 截止为 long 典型的表白式   dword byval variable as long 截止为 long 典型的表白式   hwnd, hdc, hmenu byval variable as long 截止为 long 典型的表白式等windows 句柄   int, uint byval variable as long 截止为 long 典型的表白式   long byval variable as long 截止为 long 典型的表白式   lparam byval variable as long 截止为 long 典型的表白式   lpdword variable as long 截止为 long 典型的表白式   lpint, lpuint variable as long 截止为 long 典型的表白式   lprect variable as type 自设置典型的大肆变量   lpstr, lpcstr byval variable as string 截止为 string 典型的表白式   lpvoid variable as any 任何变量(在传播字符串的功夫运用byval)   lpword variable as integer 截止为integer 典型的表白式   lresult byval variable as long 截止为 long 典型的表白式   null as any 或 byval nothing 或   byval variable as long byval 0& 或 vbnullstring   short byval variable as integer 截止为integer 典型的表白式   void sub procedure 不行用   word byval variable as integer 截止为integer 典型的表白式   wparam byval variable as long 截止为 long 典型的表白式  5、vb中举行32位动静库的证明时,因变量名是巨细写敏锐的。在赢得了须要的动静贯穿 库之后,就不妨在vb中举行挪用了。然而,因为vb不许考证运用步调传播到动静贯穿库中的参 数值能否精确,所以vb步调中洪量的api挪用大概会贬低所有运用步调的宁静性,也会减少以 后保护的难度。以是,确定在vb步调市直接挪用api因变量时要留心,但符合的运用api挪用真实 不妨灵验地普及vb步调的本能。这之间的平稳须要编制程序职员按照本质情景来控制。底下就简直引见一下在vb中挪用api因变量时须要做的处事。  要证明一个dll进程,开始须要在代码窗口的"通用(general)"局部减少一个declare语句。即使该进程归来一个值,应将其证明为function:   declare function publicname lib "libname" [alias "alias"] [([[byval] variable [as type] [,[byval] variable [as type]]...])] as type    即使进程没有归来值,可将其证明为sub:   declare sub publicname lib "libname" [alias "alias"] [([[byval] variable [as type] [,[byval] variable [as type]]...])]   缺省情景下,在规范模块中证明的dll进程,不妨在运用步调的任何场合挪用它。在其它典型的模块中设置的dll进程则是模块独占的,必需在它们前方证明private要害字,以示辨别。底下辨别引见证明语句的各个构成局部。  (一)、指定动静库:  declare语句中的lib子句用来报告visual basic怎样找到包括进程的.dll文献。 即使援用的进程属于windows中心库(user32、kernel32或gdi32),则不妨不包括文献扩充名,如:   declare function gettickcount lib "kernel32" alias "gettickcount" () as long    对于其它动静贯穿库,不妨在lib子句指定文献的路途:   declare function lzcopy lib "c:\windows\lzexpand.dll" _   (byval s as integer, byval d as integer) as long 即使未指定libname的路途,visual basic将依照下列程序搜索该文献:  ①.exe文献地方的目次  ②暂时目次  ③windows体例目次  ④windows目次  ⑤path情况变量中的目次  下表中列出了常用的操纵体例情况库文献。  动静链接库刻画  advapi32.dll高档api效劳,扶助洪量的api(个中囊括很多安定与备案上面的挪用)   comdlg32.dll通用对话框api库  gdi32.dll图形摆设接口api库  kernel32.dllwindows32位中心的api扶助  lz32.dll32位收缩例程  mpr.dll多接口路由器库  netapi32.dll32位搜集api库  shell32.dll32位shellapi库  user32.dll用户接口例程库  version.dll本子库  winmm.dllwindows多媒介库  winspool.drv后盾打字与印刷接口,包括后盾打字与印刷api挪用。  对于windows的体例api因变量,不妨运用vb供给的东西api viewer搜索某一因变量及其相 关数据构造和常数的证明,并复制到本人的步调中。  (二)、运用别号:  declare语句中的alias子句是一个可选的局部,用户不妨经过它所标识的别号对动静 库中的因变量举行援用。比方,在底下的语句中,声领会一个在vb中名为myfunction的因变量,而它在动静库mydll.dll中首先的名字是myfunctionx。   private declare function myfunction lib "mydll.dll" _    alias "myfunctionx" ( ) as long   须要提防的是,alias子句中的因变量名是巨细写敏锐的,也即是说,必需与因变量在天生时的证明(如在c源文献中的证明)普遍。这是由于32位动静库与16位动静库各别,个中的因变量名是辨别巨细写的。同样原因,即使没有运用alias子句,那么在function(或sub)后的因变量名也是辨别巨细写的。  常常在以次几种情景时须要运用alias子句:a.处置运用字符串的体例windows api进程  即使挪用的体例windows api进程要运用字符串,那么证明语句中必需减少一个alias 子句,以指定精确的字符集。包括字符串的体例windows api因变量本质有两种方法:ansi和unicode( 对于ansi和unicode两种字符集的辨别将在反面精细阐明)。所以,在windows头文献中,每 个包括字符串的因变量都同声有ansi本子和unicode本子。比方,底下是setwindowtext因变量 的两种c谈话刻画。不妨看到,第一个刻画将因变量设置为setwindowtexta,尾部的"a" 表白它是一个ansi因变量:   winuserapi bool winapi setwindowtexta(hwnd hwnd, lpcstr lpstring);   第二个刻画将它设置为 setwindowtextw, 尾部的"w" 表白它是一个 unicode 因变量:    winuserapi bool winapi setwindowtextw(hwnd hwnd, lpcwstr lpstring);   由于两个因变量本质的称呼都不是"setwindowtext",要援用精确的因变量就必 须减少一个alias子句:private declare function setwindowtext lib "user32" _alias "setwindowtexta" (byval hwnd as long, byval _lpstring as string) as long   该当提防,对于vb中运用的体例windowsapi因变量,该当指定因变量的ansi本子,由于只 有windowsnt才扶助unicode本子,而windows95不扶助这个本子。仅当运用步调只运转 在windowsnt平台上的功夫才不妨运用unicode本子。  b.因变量名是不规范的称呼  偶尔,个其余dll进程的称呼不是灵验的操作符。比方,它大概包括了不法的字符(如连 字符),大概称呼是vb的要害字(如getobject)。在这种情景下,不妨运用alias要害字。例 如,操纵情况dlls中的某些进程名以次划线发端。纵然在vb操作符中承诺运用操作符,然而 下划线不许动作操作符的第一个字符。为了运用这种进程,必需先证明一个称呼正当的进程, 而后用alias子句援用进程的如实称呼:declare function lopen lib "kernel32" alias "_lopen" _(byval lppathname as string, byval ireadwrite _as long) as long   在上例中,lopen是vb中运用的进程称呼。而_lopen则是动静贯穿库中不妨辨别的名 称。  c.运用序号标识dll进程  除去运用称呼除外,还不妨运用序号来标识dll进程。某些动静贯穿库中不包括进程的称呼,在证明它们包括的进程时必需运用序号。同运用称呼标识的dll进程比拟,即使运用序号,在最后的运用步调中耗费的外存将比拟少,并且速率会快些。然而,一个简直的api的序号 在各别的操纵体例中大概是各别的。比方getwindowsdirectory在win95下的序号为432,而在windowsnt4.0下为338。总之,即使蓄意运用步调不妨在各别的操纵体例下运转,那么最佳不要运用序号来标识api进程。即使进程不属于api,大概运用步调运用的范畴很有 限,那么运用序号仍旧有长处的。  要运用序号来证明dll进程,alias子句中的字符串须要包括进程的序号,并在序号的 前方加一个数字标志字符(#)。比方,windowskernel中的getwindowsdirectory因变量的序 号为432;不妨用底下的语句来证明该dll进程:declare function getwindowsdirectory lib "kernel32" _alias "#432" (byval lpbuffer as string, _byval nsize as long) as long   在这边,不妨运用大肆的正当称呼动作进程的称呼,vb将用序号在dll中探求进程。  为特出到要证明的进程的序号,不妨运用dumpbin.exe等适用东西(dumpbin.exe是microsoft visualc++供给的一个适用东西,它的运用证明不妨拜见vc的文书档案)。运用dumpbin,不妨索取出.dll文献中的百般消息,比方dll中的因变量列表,它们的序号以及与代码相关的其它消息。  (三)、运用值或援用传播  在缺省的情景下,vb以援用办法传播一切参数(byref)。这表示着并没有传播本质的参 数值,vb只传播了数据的32位地方。其余有很多dll进程诉求参数以值办法传播(byval)。这表示着它们须要本质的数据,而不是数据的外存地方。即使进程须要一个传值参数,而传播给它的参数是一个南针,那么因为获得了缺点的数据,该进程将不许精确地处事。  要使参数以运用值办法传播,在declare语句中须要在参数证明的前方加上byval要害字。比方invertrect进程诉求第一个参数用传值办法传播,而第二个用援用办法传播:declare function invertrect lib "user32" alias _"invertrecta" (byval hdc as long, lprect as rect) as long   动静贯穿库的参数传播是一个搀杂的题目,也是vb中挪用动静贯穿库时最简单展示缺点的场合。参数典型或传播办法的证明缺点都大概引导运用步调展示gpf(通用养护缺点),以至使操纵体例解体,所以咱们将在反面特意精细地计划这个题目。  (四)、精巧的参数典型  某些dll进程的同一个参数不妨接收多种数据典型。即使须要传播多种典型的数据,可 以将参数证明为asany,进而废除典型控制。比方,底下的证明中的第三个参数(lpptasany) 既不妨传播一个point构造的数组,也不妨传播一个rect构造:declare function mapwindowpoints lib "user32" alias _"mapwindowpoints" (byval hwndfrom as long, _byval hwndto as long, lppt as any, _byval cpoints as long) as long  asany子句供给了确定的精巧性,然而,因为它不举行任何的典型查看,危害也随之增 加。所以在运用asany子句时,必需提防查看一切参数的典型。  精确的因变量证明是在VB中调用动态连接库的基础,但要想在vb顶用对、用好动静库中的 因变量,只是有证明仍旧远远不够的。前方仍旧说过,因为vb不许考证运用步调传播到动静贯穿 库中的参数值能否精确,所以就诉求步调员应付参数典型有特殊精细的领会,要不很简单引 起运用步调爆发通用养护错或引导潜伏的bug,贬低软硬件的真实性。底下将参数典型分为大略数据典型、字符串、和用户自设置典型三种辨别举行计划。  (1)、大略数据典型:  大略数据典型是指numeric数据典型(囊括integer、long、single、double、currency典型)、byte数据典型和boolean数据典型。它们的共通的特性是构造大略,操纵体例在处置时不用举行特出的变换。  大略数据典型参数的传播比拟大略。咱们领会,在vb中传播参数的办法有两种:传值(byval) 和传址(byref),缺省的办法是传址。所谓传值,即是对一个变量的简直值举行传播;而传址则 是传播变量的地方。比方,在vb步调中须要将一个整型变量m=10的值传进动静库,即使用传值 办法,那么传进动静库的值即是10,而在传址办法下,传入的则是变量m的地方,十分于c/c++ 中&m的值。须要提防的是,以传值办法传进动静贯穿库的变量,其值在动静库中是不许 被变换的;即使须要在动静贯穿库中窜改传入参数的值,则必需运用传址办法。普遍来说,在vb 和动静贯穿库之间传播单个的大略数据典型,只有提防了之上几个上面就不妨了。当须要将 一个大略数据典型的所有数组传进动静库时,必需将相映参数证明为传址办法,而后把数组 的第一个元素动作参数字传送入,如许在动静贯穿库中就获得了数组的首地方,进而不妨对所有 数组举行考察。比方,声领会一个名为readarray的dll进程,诉求传入一个整型数组aarray:declare function readarray lib "mydll.dll" _(aarray as integer) as integer 在挪用时不妨沿用如次办法:dim ret,i(5) as integer… …ret = readarray(i(0)) ' 将所有数组传入动静贯穿库 (2)、字符串参数的传播:  与大略数据典型比拟,字符串典型(string、string*n)的参数传播要搀杂得多,这主假如windows 95 api和vb运用的字符串典型各别的来由。vb运用被称为bstr的string数据典型,它是由机动化(往日被称为ole automation)设置的数据典型。一个bstr由头部和字符串构成,头部包括了字符串的长度消息,字符串中不妨包括嵌入的null值。大局部的bstr是 unicode的,即每个字符须要两个字节。bstr常常以两字节的两个null字符中断。下图表白 了一个bstr典型的字符串。  (前缀)atest\0  头部bstr指向数据的第一个字节  另一上面,大局部的dll进程(囊括windows 95 api中的一切进程)运用lpstr典型字符串,这是指向规范的以null中断的c谈话字符串的南针,它也被称为asciiz字符串。lpstr 没有前缀。下图表露了一个指向asciiz字符串的lpstr。  atest\0  lpstr指向一个以null结果的字符串数据的第一个字节  即使dll进程须要一个lpstr(指向以null中断的字符串的南针)动作参数,不妨在vb 中将一个字符串以传值的办法传播给它。由于指向bstr的南针本质指向以null值中断的字符串的第一个数据字节,以是对于dll进程来说,它即是一个lpstr。如许传入动静贯穿库的字符串,dll进程也不妨对它举行窜改,纵然它是以传值办法传入的。惟有当dll进程须要一个指向lpstr的南针时,才以传址的办法传入字符串,这时候dll进程获得的是一个指向字符串南针的南针(十分于c/c++中的char**),而不是常常所用的字符串的首地方(十分于c/c++中的char*)。  当须要把一个字符串数组所有传入动静贯穿库时,情景就变得搀杂多了,用传播大略数据典型数组的办法来传播字符串数组是行不通的。当咱们以传值的办法将一个字符串数组的第一个元素传进动静贯穿库时,dll进程获得的本质上是该元素压入仓库段后的地方,而不是数据段中所有数组的首地方。也即是说,这时候dll进程只能获得数组的第一个元素,而没辙考察所有数组。而以传址办法传入第一个元素时,dll进程只能获得指向该元素在仓库段中地方的南针,同样没辙考察所有数组。这不许不说是vb的一个不及。所以,在步调安排中,即使真实须要将所有字符串数组传入动静库,就必需采用其它本领。  咱们领会,在vb中,有一种byte数据典型。每个byte型变量占一个字节,不含标记位,因 此所能表白的范畴为0到255。这种数据典型是特意用来寄存二进制数据的。为了将所有字符 串数组传进动静库,不妨用字节数组来生存字符串。因为byte是一种大略数据典型,所以字节 数组的传播利害常大略的。开始,须要把一个字符串精确地变化成一个字节数组。这要波及一 些字符集的常识。windows 95和vb运用各别的字符集,windows 95 api运用的是ansi或dbcs 字符集,而vb运用的则是unicode字符集。所谓ansi字符集,是指每个字符都用一个字节表白, 所以最多只能有28=256个各别的字符,这对于英语来说仍旧充满了,但不许实足扶助其它语 言。dbcs字符集扶助很多各别的东亚谈话,如华语、日语和朝鲜语,它运用数字0-255表白ascii 字符,其它大于255或小于0的数字表白该字符属于非拉丁字符集;在dbcs中,ascii字符的长 度是一个字节,而华语、日语和其它东亚字符的长度是2个字节。而unicode字符集则实足用 两个字节表白一个字符,所以最多不妨表白216=65536个各别字符。也即是说,ansi字符会合 一切的字符都只占一个字节,dbcs字符会合ascii字符占一个字节,中国字占两个字节,unicode 字符会合每个字符都占两个字节。因为vb与windowsapi运用的字符集各别,所以在举行字符 串到字节数组的变换时,当用asc因变量博得一个字符的字节码后,须要确定它能否是一个ascii 字符;即使是ascii字符,则在变换后的字节数组中就只占一个字节,要不要占两个字节。  底下给出了变换因变量:getchar byte获得一个字符的高字节或低字节,它的第一个参数 是一个字符的ascii码,第二个参数是标记取高字节仍旧低字节;strtobyte按dbcs或ansi格 式将一个字符串变换成一个字节数组,第一个参数是待变换的字符串,第二个参数是变换后的一个定长字节数组,若该数组长度不及以寄存所有字符串,则截去超长的局部;changestrarytobyte 运用前两个因变量将字符串数组变换成字节数组,第一个参数是定长的字符串数组,个中每个元素都是一个字符串(各个元素包括的字符数不妨各别),第二个参数是一个变长的字节数组, 生存变换后的截止。   function getcharbyte(byval onechar as integer, byval ishighbyte as boolean) as byte ' 该因变量赢得一个字符的高字节或低字节 if ishighbyte thenif onechar >= 0 thengetcharbyte = cbyte(onechar \ 256) '右移8位,获得高字节elsegetcharbyte = cbyte((onecharand &h7fff) \ 256) or &h80end ifexit functionelsegetcharbyte = cbyte(onechar and &hff) '樊篱掉高字节,获得低字节exit functionend ifend functionsub strtobyte(strtochange as string, bytearray() as byte)'该因变量将一个字符串变换成字节数组dim lowbound, upbound as integerdim i, count, length as integerdim onechar as integercount = 0length = len(strtochange)lowbound = lbound(bytearray)upbound = ubound(bytearray)for i = lowbound to upboundbytearray(i) = 0 '初始化字节数组nextfor i = lowbound to upboundcount = count + 1if count <= length thenonechar = asc(mid(strtochange, count, 1))if (onechar > 255) or (onechar < 0) then'该字符利害ascii字符bytearray(i) = getcharbyte(onechar, true) '获得高字节i = i + 1if i <= upbound then bytearray(i)= getcharbyte(onechar, false)'获得低字节else'该字符是ascii字符bytearray(i) = onecharend ifelseexit forend ifnextend subsub changestrarytobyte(strary()as string, byteary() as byte)'将字符串数组变换成字节数组dim lowbound, upbound as integerdim i, count, startpos, maxlen as integerdim tmpbyte() as bytelowbound = lbound(strary)upbound = ubound(strary)count = 0redim byteary(0)for i = lowbound to upboundmaxlen = lenb(strary(i))redim tmpbyte(maxlen + 1)redim preserve byteary(count + maxlen + 1)call strtobyte(strary(i), tmpbyte) '变换一个字符串startpos = countdobyteary(count) = tmpbyte(count - startpos)count = count + 1if byteary(count - 1) = 0 then exit doloop '将每一个字符串对应的字节数组按程序填入截止数组中redim preserve byteary(count - 1)next iend sub  底下看一个变换的例子:dimresultary()asbytedimsomestr(2)asstringsomestr(0)="尝试1"somestr(1)="尝试222"somestr(2)="尝试33"callchangestrarytobyte(somestr,resultary)'变换字符串数组   当变换实行此后,察看字节数组resultary,个中包括了21个元素,顺序是:178,226,202,212,49,0,178,226,202,212,50,50,50,0,178,226,202,212,51,51,0。个中,[178,226]是"测"的字节码,[202,112]是"试"的字节码,49,50,51 辨别为字符1、2、3的ascii码。看来,过程变换后,字符串数组中的各个元素按程序放在了字节数组中,彼此间以中断符0分割。  如许,字符串数组就十足变换成了字节数组,而后只有将字节数组的第一个元素以传址的办法传入动静贯穿库,dll进程就不妨精确地考察数组中的一切字符串了。然而,运用这种本领,当dll进程处置中断归来vb时,vb获得的仍旧是字节数组。即使须要在vb中再次获得该字节数组表白的字符串,还要把所有字节数组从新以0为分隔符分红多个子数组(每个子数组都对应从来字符串数组中的一个元素),而后运用vb因变量strconv将每个子数组变换成字符串(变换时第二个参数选vbunicode),就不妨表露或举行其它操纵了。比方,个中一个子数组的名字是subary,则因变量strconv(subary,vbunicode)就归来了它所对应的字符串。  总之,vb运用步调和动静库间字符串参数的传播是一个比拟搀杂的进程,运用时要特殊精心。同声应尽大概制止传播字符串数组典型的参数,由于这很简单惹起下标越界、仓库溢出等重要缺点。  (3)、用户自设置典型(user-defined type)参数的传播  用户自设置典型在vb中是一种要害的数据典型,它为编制程序者供给了很大的精巧性,使开拓职员不妨按照须要结构本人的数据构造。它十分于c/c++中的构造典型(structure)。在vb中,承诺步调员以传址的办法将自设置数据典型参数字传送入动静库,dll进程也不妨将窜改后的参数归来vb步调。然而,在vb中仍旧不扶助以传值的办法传播用户自设置典型参数。  传播用户自设置典型参数时,必需保证vb中的数据典型的分子与动静库中的结形成员是逐一对应的,所占空间也必需庄重普遍。这边所说的逐一对应,不只是指vb 中的一切结形成员在动静库的构造中都必需有对应的元素,并且它们在数据构造中设置的程序也必需庄重普遍,这是vb中运用的"数据结形成员对齐办法"确定的。在vb 中,数据构造运用双字对齐办法(4-byte alignment),所以,在用户本人天生用来vb 挪用的动静贯穿库时,也必需把编写翻译选项"structure member alignment" 设为4字节(如前文所述)。  所谓结形成员对齐办法是指一个数据构造里面,其分子的陈设办法。比方,在vb中,其对齐办法是4字节,这就好象在一个数据构造里面分红了很多个4字节巨细的小单位,即使相邻 两个或多个数据分子的巨细不妨放在一个单位中,那么就放在一道;要不那些小单位中大概 会展示未用的空字节。咱们来看底下一个数据典型:type testtypem1 as integerm2 as bytem3 as longend type   它的三个分子的巨细加起来是2+1+4=7。然而,因为m1和m2的字节总参谋长度是3,小于4,它 们就寄存于一个单位中;但该单位剩下的一个字节不及以放下一个long型的分子m3,所以m3 就被放鄙人一个单位中,它们之间就有了一个未用的空字节;所以,所有构造所占本质长度是8 字节。同理,即使将m3和m2的场所调换一下,它所占的尺寸就形成了9字节。看来,分子在构造 中的证明程序也利害常要害的。  常常,当一个用户自设置典型中不包括字符串时,向动静贯穿库中传播该典型的参数是没有什么题目的。即使只传播一个自设置典型变量,则既不妨传播该变量名,也不妨传播该变 量的第一个分子,它们的功效是一律的,都是将该变量的地方传进了动静库;同样,即使要传播一个自设置典型的数组,则既不妨传播该数组的第一个元素,也不妨传播第一个元素的第一个分子。然而,即使用户自设置典型中包括字符串典型时,又该怎样与动静贯穿库传播参数呢?谜底是令人可惜的:在vb中,你没辙将一个包括字符串分子的用户自设置典型变量或数 组安定、精确地传入动静库中。即使你如许做了,纵然某次幸运获得了精确的截止,在其背地也湮没着很多沉重的伤害。所以,即使确定要在用户自设置典型中包括字符串变量,而且该典型的变量又要动作参数字传送入动静库时,你最佳窜改典型设置,把个中的字符串分子用相映的字节数组典型替代掉(变换本领可拜见前文),如许就不妨在vb 和动静库间传播这种典型的参数了。  其余,在vb 中还不妨把一个因变量的南针传播到动静库中,本领也并不搀杂。但笔者激烈倡导最佳不要这么做,由于如许一来vb 运用步调就简直实足流失了它所应有的安定性。即使 真实须要传播因变量南针的话,那么仍旧编一个c/c++ 的步调来实行这项处事吧。  总之,在vb中挪用dll进程是一个比拟搀杂的题目,编制程序职员必需很好地控制,本领到达既普及了步调功效,开辟了步调功效,又不贬低步调安定性的手段。其余须要更加指出的一点是,在正文中提到的一切动静贯穿库,都是指没有运用机动化(ole automation)本领的动静库,windows api保卫世界和平大会普遍用户自编的动静贯穿库都是这种典型的。对于运用了ole automation本领的动静贯穿库,其参数传播的办法有所各别,读者群不妨参见相关ole 本领的书本,在此不复波及。

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.