CopyMemory函数

CopyMemory函数CopyMemory 函数下面我们来熟悉一下本文重点讨论的这个函数 vb viewplaincop Declare nbsp Sub nbsp CopyMemory nbsp Lib nbsp kernel32 nbsp Alias nbsp RtlMoveMemor nbsp nbsp nbsp nbsp nbsp nbsp nbsp pDest nbsp As nbsp Any nbsp pSource nbsp As nbsp Any nbsp ByVal nbsp byteLen nbsp As nbsp Long nbsp nbsp

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,那么源地址就是变量的值

    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的形式:
表格-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拷贝字符串的种种猫腻(一)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201648.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:56
下一篇 2026年3月20日 上午8:56


相关推荐

  • Android startActivityForResult用法

    Android startActivityForResult用法一、介绍当我们在第一个Activity打开第二个Activity时,第二个Activity关闭并想返回数据给第一个Activity时,我们就可以使用startActivityForResult进行传值。用到的几个方法介绍:1.startActivityForResult(Intentintent,intrequestCode)requestCode:如果>=…

    2022年7月11日
    19
  • pycharm离线安装python第三方库的方法

    pycharm离线安装python第三方库的方法1 下载 whl 或者 tar gz 文件 最好放在无中文的路径下 建议放在盘根目录一级目录下 方便后面安装 2 启动 pycharm 点击下部 Terminal 3 在 Terminal 中进入文件下载的目录路径 cd 盘符 下载文件夹路径 a 对于 whl 文件 输入 pyinstallerx whlb 对于 tar gz 文件 解压后 进入该解压文件夹路径 输入 pythonsetup pyinstall

    2026年3月27日
    2
  • 【Ubuntu 】Ubuntu 更换国内源—解决终端下载错误或速度慢的问题「建议收藏」

    【Ubuntu 】Ubuntu 更换国内源—解决终端下载错误或速度慢的问题「建议收藏」前言:安装好ubuntu双系统后,默认的软件更新源是国外的,在国内使用速度很慢,用”aptinstallxxx”安装软件时可能出现”网络不可达”、”你的网络需要认证吗”、”无法定位软件包”等错误,所以我们需要更换成国内的源,这样才能正常安装和更新软件。目录一、ubuntu16.04更换国内源二、ubuntu18.04更换国内源三、UbuntuROS更换国内源

    2022年5月14日
    51
  • 算法学习–分酒问题(BFS)[通俗易懂]

    算法学习–分酒问题(BFS)[通俗易懂]有4个红酒瓶子,它们的容量分别是:9升,7升,4升,2升开始的状态是[9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?本题就是要求你编程实现最小操作次数的计算。输入:最终状…

    2022年10月19日
    4
  • PyCharm 2022.01.13 永久激活码(JetBrains全家桶)

    (PyCharm 2022.01.13 永久激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年4月1日
    225
  • 架构 Roadmap 笔记分享 (2015 年)

    架构 Roadmap 笔记分享 (2015 年)

    2021年11月24日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号