CopyMemory函数

(1) VatPtr/ StrPtr/ ObjPtr

VarPtr:返回变量地址

StrPtr:返回真正的UNICODE字符串缓冲区的地址

ObjPtr:返回任何对象变量引用的地址

  它们是VB提供给我们的好宝贝,它们是VBA函数库中的隐藏函数。为什么要隐藏?因为VB开发小组,不鼓励我们用指针嘛。

  VarPtr返回的是变量所在处的内存地址,也可以说返回了指向变量内存位置的指针,它是我们在VB里处理指针最重要的武器之一。
 Private Declare Function ObjPtr Lib "MSVBVM60" Alias "VarPtr" (var As Object) As Long
 Private Declare Function VarPtr Lib "MSVBVM60" (var As Any) As Long

没有StrPtr,是因为VB对字符串处理方式有点不同,这方面的问题太多,

(2)  ByVal和ByRef

  ByVal传递的参数值,

  ByRef传递的参数的地址。我们不用去区别传指针/传地址/传引用的不同,在VB里,它们根本就是一个东西的三种不同说法,即使VB的文档里也有地方在混用这些术语(但在C++里的确要区分指针和引用)

  一定要搞清在里面的CopyMemory调用中,在什么地方要加ByVal,什么地方不加(不加ByVal就是使用VB缺省的ByRef),准确的理解传值和传地址(指针)的区别,是在VB里正确使用指针的基础。

(3)AddressOf

  它用来得到一个指向VB函数入口地址的指针,不过这个指针只能传递给API使用,以使得API能回调VB函数。

(4)CopyMemory函数

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal byteLen As Long)  

  功能是将从pSource指针所指处开始的长度为byteLen的内存拷贝到pDest所指的内存处。

  其中源地址和目标地址都是声明为Any类型。
下面是CopyMemory对不同形式参数的理解:
(1) 传一个变量给pSource,那么源地址就是变量所在的地址
(2) 以ByVal形式传一个变量给pSource,那么源地址就是变量的值

 例如:
 Dim k As Long
 k = 5
   '从保存常数40000的临时变量处拷贝4个字节,到变量k所在的内存中。
    CopyMemory     ByVal VarPtr(k), 40000, 4      '[ByVal VarPtr(k)把K的地址本身当作值传给函数] 
 CopyMemory                          k  , 40000, 4     'K传递函数的缺省方法是ByRef, 因此, 也可这样写

CopyMemory ByVal VarPtr(k), ByVal 40000, 4  
       ‘意思是从地址40000拷贝4个字节到变量k所在的内存中。由于地址40000所在的内存未知或不能访问,结果错误
    CopyMemory VarPtr(k), 40000, 4

意思就成了,从保存常数40000的临时变量处拷贝4个字节,由于缺省是ByRef,VarPtr(k)为K的地址,将会成为一临时变量,再得到此临时变量的地址,传递给函数。此临时变量的内存地址无任何意义,k的值并没有变。

(5)字符串变量CopyMemory

     字符串变量的值是个指针,指向字符串缓冲区的地址,也就是StrPtr(Str1)。
     以ByVal形式传一个字符串变量给pSource,那么源地址就是字符串变量的值,也就是字符串缓冲区的地址。
 
下表总结了几种常见的传参数给CopyMemory的形式:
注:
(1)取到的内容根据byteLen实际规定的字节数的多少,可能有所不同,这里只是个大概。
(2)带高亮的两行,VB对字符串参数做了自动的UA转换,所以实际的CopyMemory动作针对的是由String1转换得到的ANSI字符串_tmp1而进行的。
(3)字节数那一列给出了要取到有效的数据byteLen参数可以使用的数字范围。简单的说,如果pSource的参数是字符串类型的话,那么byteLen的字节数要取为String1对应的ANSI字符串的长度。要理解这个也容易,你只要记住CopyMemory这时候实际上是对ANSI字符串做操作就可以了。而如果不发生字符串转换的话,像表里第4行,那么你就要拷贝String1的LebB长度。这也好理解,不发生转换的话,CopyMemory实际上是在直接拷贝Unicode字符串的内容啊。
 
Sub SwapPtr(sA As String, sB As String)
Dim lTmp As Long
CopyMemory lTmp, ByVal VarPtr(sA), 4
CopyMemory ByVal VarPtr(sA), ByVal VarPtr(sB), 4
CopyMemory ByVal VarPtr(sB), lTmp, 4
End Sub
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
'交换两个字符串最快的方法
Sub SwapStrPtr3(sA As String, sB As String)
Dim lTmp As Long
Dim pTmp As Long, psA As Long, psB As Long
pTmp = StrPtr(sA):              psA = VarPtr(sA):                   psB = VarPtr(sB)
CopyMemory ByVal psA, ByVal psB, 4
CopyMemory ByVal psB, pTmp, 4
End Sub
参考:VB中利用CopyMemory使用指针
VB6中用CopyMemory拷贝字符串的种种猫腻(一)

CopyMemory函数相关推荐

  1. VB中CopyMemory函数

    vb中copymemory函数的使用挺耐人寻味的.copymemory的使用说明资料书上就一句"该函数用于将一块内存的数据从一个位置复制到另一个位置".其参数数据类型destina ...

  2. 测试CopyMemory函数的速度

    函数简介 CopyMemory函数的功能:将一块内存的数据从一个位置复制到另一个位置.其中,两个内存块不能有重叠部分. 测试环境 操作系统版本:windows 7 旗舰版 sp1 系统类型:64位 处 ...

  3. linux网络编程 copymemory,在VB6中用CopyMemory拷贝字符串的种种猫腻(一)

    本文来自此帖的冗长讨论,感谢Tiger_Zhao的全程指点和陈辉.阿勇.马云剑等很多朋友的热心参与.本文其他部分在:(二).(三).(四). 话说VB6是个很认真细致的妈妈,它会悄没声地帮你做很多事. ...

  4. DLL(MFC)通过Window消息向C#程序传递数据

    这是我在用C#开发IOServer遇到的一个问题,该程序需要用到原先用MFC开发的DLL,最大问题是该dll运行过程中的一些信息,通过window消息向指定的hwnd(窗体句柄)发送数据.数据的指针放 ...

  5. PE文件格式和ELF文件格式(上)----PE文件

    PE文件格式详解 作者:MSDN 译者:李马 Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式.PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy ...

  6. 在vb中使用Iphlpapi.dll获取网络信息(上)

    ※================================================================== ※本连载文章说明: ※1.连载首发于<软件报>(ht ...

  7. 接着外挂教程 VB 从零开始编外挂

    接着外挂教程 VB 从零开始编外挂 需要VBAPI函数: FindWindow←寻找窗口列表中第一个符合指定条件的顶级窗口 GetWindowThreadProcessId←获取与指定窗口关联在一起的 ...

  8. VB 从零开始编外挂

    需要VB API函数: FindWindow ←寻找窗口列表中第一个符合指定条件的顶级窗口 GetWindowThreadProcessId ←获取与指定窗口关联在一起的一个进程和线程标识符 ---- ...

  9. PE文件格式详解(7)

    调试信息段,.debug 调试信息位于.debug段之中,同时PE文件格式也支持单独的调试文件(通常由.DBG扩展名标识)作为一种将调试信息集中的方法.调试段包含了调试信息,但是调试目录却位于早先提到 ...

最新文章

  1. form表单会跨域_前端跨域So Easy
  2. 有线路由器与无线路由器混合使用
  3. pixysoft.framework.messageflow enterprise edition 开发实录
  4. 未来新一代计算机的发展方向,未来计算机的发展方向 (2)
  5. Redis 3.0.501 学习使用(1)
  6. 大牛书单 | 云原生技术领域好书推荐
  7. MySQL数据分析-(1) 数据库前言
  8. [教程]centos下设置网卡
  9. Java 发送 Http请求工具类
  10. linux怎么卸载vsftpd软件,vsftpd配置详解之软件安装和卸载
  11. 做正确的事永远都不迟
  12. Babel 是什么?· Babel 中文文档
  13. java按钮权限控制_aop (权限控制之功能权限)
  14. 区块链可扩展性技术:闪电网络
  15. Linux中top命令参数说明
  16. 计算机专业就业方向湖北,湖北成考计算机类专业就业前景怎么样?
  17. 学生-课程数据库—初识sql语句(04)(注释版)
  18. 涉外诉讼公证认证北京代办流程时间
  19. 【博学谷学习记录】超强总结,用心分享 | 架构师 Netty框架学习总结
  20. FusionCharts在Java中的基本使用!

热门文章

  1. 陈景润“1+2”定理与黎曼“1/2”猜想
  2. MYSQL做BCV备份数据库,每天定时自动备份方案与实现
  3. 数据结构:哈夫曼树【转载自mcgrady https://www.cnblogs.com/mcgrady/p/3329825.html#_label0】
  4. 梯度 方向导数 偏导数的一些整理
  5. 如何快速高效地进行seo域名批量查询
  6. 错过了竟是一生的遺憾
  7. 毛笔行草书法-渔歌子
  8. cips2016-中文信息处理发展阅读笔记
  9. scala的传名参数和传值参数
  10. Redis持久化策略