• VB指针 与CopyMemory



    体会ByVal和ByRef
    Dim k As Long

    CopyMemory ByVal VarPtr(k), 40000, 4
    等同于k=40000;从保存常数40000(缺省ByRef)的临时变量处(地址)拷贝4个字节到变量k所在的内存中。

    CopyMemory ByVal VarPtr(k), ByVal 40000, 4
    k=(40000的地址);从地址40000拷贝4个字节到变量k所在的内存中。由于地址40000所在的内存我们无权访问,操作系统会给我们一个Access Violation内存越权访问错误

    CopyMemory VarPtr(k), 40000, 4
    从保存常数40000的临时变量处(地址)拷贝4个字节(即40000),到保存变量k所在内存地址值的临时变量处。这不会出出内存越权访问错误,但k的值并没有变。

    '看看我们的东西被拷贝到哪儿去了
    Sub TestCopyMemory()
      Dim i As Long, k As Long
      k = 5
      i = VarPtr(k)
      CopyMemory i, 40000, 4 'NOTE4:
      Debug.Print k
      Debug.Print i

      i = VarPtr(k)
      CopyMemory ByVal i, 40000, 4 'NOTE5:
      Debug.Print k
    End Sub

       程序输出:
    5
    40000
    40000
    由于NOTE4处使用缺省的ByVal,传递的是i的地址(也就是指向i的指针),所以常量40000拷贝到了变量i里,因此i的值成了40000,而k的值却没有变化。但是,在NOTE4前有:i=VarPtr(k),本意是要把i本身做为一个指针来使用。这时,我们必须如NOTE5那样用ByVal来传递指针i,由于i是指向变量k的指针,所以最后常量40000被拷贝了变量k里

    '使用更安全的CopyMemory,明确的使用指针!
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
    Sub SwapStrPtr2(sA As String, sB As String)
      Dim lTmp As Long
      Dim pTmp As Long, psA As Long, psB As Long
      pTmp = VarPtr(lTmp): psA = VarPtr(sA): psB = VarPtr(sB)
      CopyMemory pTmp, psA, 4
      CopyMemory psA, psB, 4
      CopyMemory psB, pTmp, 4
    End Sub

       注意,上面CopyMemory的声明,用的是ByVal和long,要求传递的是32位的地址值,当我们将一个别的类型传递给这个API时,编译器会报错,比如现在我们用下面的语句:

  • 相关阅读:
    叶问14
    叶问13
    叶问12
    叶问11
    叶问10
    叶问9
    Java三种循环之间的区别
    利用Java对象数组制作简易学生管理系统
    什么叫java方法重载?
    Java编译器的常量优化
  • 原文地址:https://www.cnblogs.com/whchensir/p/4135560.html
Copyright © 2020-2023  润新知