您现在的位置: 中国男护士网 >> 考试频道 >> 计算机等级 >> 二级辅导 >> VB >> 辅导 >> 正文    
  API中VB字符串作参数传递的本质论 【注册男护士专用博客】          

API中VB字符串作参数传递的本质论

www.nanhushi.com     佚名   不详 

  问题背景:
  前几天在论坛中看到有一个提问的问题,内容是:
  模块中的代码:
  Option Explicit
  Public Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long’声明获取计算机名的API函数
  窗体中的代码:
  Option Explicit
  Private Sub Command1_Click()
   Dim computername As String
   Dim length As Long
   length = 255
   str = String(length, 0)
   GetComputerName computername, length
   Debug.Print computername,
  End Sub
  以上程序的功能是获取计算机名。
  大家看上面API中的lpBuffer这个形参被声明为Byval(传值)方式。那么在调用之后API函数却可以通过computername这个实参传回计算机名,那么形参不是被声明为传值调用方式吗?即形参值的改变不会影响到实参,可是这里调用API函数后却可以通过实参返回值,这是到底是什么原因呢?
  相关知识:
  大家都知道,VB中没有C语言中的指针类型。C语言中只有字符数据类型,即字符变量只能存放一个字符,而没有字符串变量,它操作字符串是通过字符型指针来实现的,它的特点是通过’\0’来判断字符是否结束的。而VB有字符串变量类型,一种变长,一种是定长的。并且VB字符串具体自动保护功能。
  例如:dim str as string * 6
      str=”abcdef”
      debug.print str’那么将显示abcdef
      str=”abcdefghijklmnopq”
      debug.print str’还显示abcdef,说明它具有保护功能,将超过的字符截掉
  在VB中使用的字符是一种叫做BSTR格式的字符串指针类型。


  字符个数描述符由VB来使用,BSTR指针直接指向第一个字符。
  因为大多数API函数是用C或C++来编写的,在C/C++(API)中使用叫做LPSTR类型的指针。


  VB中字符串变量在内存中的存储状态图:


  从上图可知:字符串变量X的地址与实际字符串的地址不同,也就是说字符X变量中实际上是存放的字符串的首地址这一点是和C/C++相同的。其实图中descriptor这个描述符就是C中的字符串指针地址。当BSTR指针在忽略字符个数描述前缀的情况下是与LPSTR指针是相同的,在调用API时可以将BSTR以传值方式传递给API。

  采用传值方式传递时实际上传递的是实参中所存放的字符串的首地址,当调用过API后,可以通过它来返回数据,API修改传送给它的那个地址所指向的字符串数据,而没有修改实参字符变量内的内容,所以可以返回数据。即并没有与高级语言中所规定的传值方式调用方式的形参改变不影响实参的规则相冲突。

  实例:

  模块中的代码:

  Option Explicit

  Public Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

  窗体中的代码:

  Option Explicit

  Private Sub Command1_Click()

   Dim str As String

   Dim str1 as String

   Dim length As Long

   length = 255

   str = String(length, 0)

   str1=str

   Debug.Print VarPtr(str),”     “,varptr(str1)

   Debug.Print StrPtr(str),”      ”,strptr(str1)

   Debug.Print

   GetComputerName str, length

   Debug.Print str

   Debug.Print VarPtr(str)

   Debug.Print StrPtr(str), Len(str), length

  End Sub

  在立即窗口中可以看到运行结果。字符串变量的地址与字符串的地址不同。

  还可以看到字符串变量str与str1的地址不同,而且字符串地址也不同,这说明在进行赋值操作,并不是将字符的首地址赋给str1而是在内存中另开一空间用来存放字符串。而在C语言内则可以使多个字符型指针变量指向同一个字符串的首地址。

  当将API中的ByVal lpBuffer As String传值方式改为:ByRef lpBuffer As String传址方式时,运行程序中出错,VB编程环境将崩溃。

  出错图:

  因为传址时将变量本身的地址传给了API,并没有将字符串的首地址传给API,所以API在修改数据时造成访问错误。

  总结:

  不能用传址方式来调用API,如果用传址方式的话那么传递的是指向指针的指针,API将不能返回数据,并且造成访问数据出错,所以需要用ByVal传递字符串指针。

 

文章录入:杜斌    责任编辑:杜斌 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     

    联 系 信 息
    QQ:88236621
    电话:15853773350
    E-Mail:malenurse@163.com
    免费发布招聘信息
    做中国最专业男护士门户网站
    最 新 热 门
    最 新 推 荐
    相 关 文 章
    没有相关文章
    专 题 栏 目

      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)                            【进男护士社区逛逛】
    姓 名:
    * 游客填写  ·注册用户 ·忘记密码
    主 页:

    评 分:
    1分 2分 3分 4分 5分
    评论内容:
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。