zoukankan      html  css  js  c++  java
  • 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时,编译器会报错,比如现在我们用下面的语句:

  • 相关阅读:
    nodejs + typescirpt + vs code
    NodeJs使用nodejs-websocket + protobuf
    Windows10环境下使用VisualSVN server搭建SVN服务器
    微信小游戏下socket.io的使用
    JS中实现种子随机数
    帧同步和状态同步
    EgretPaper学习笔记一 (安装环境,新建项目)
    反编译微信小游戏
    微信小游戏 小程序跳转修改 不支持动态更新,只能在发布时修改
    HTML5实现本地JSON文件的读写
  • 原文地址:https://www.cnblogs.com/whchensir/p/4135560.html
Copyright © 2011-2022 走看看