VB 中 copymemory的有关问题
dim a() as long
dim b() as byte
copymemory b(0),byval "1234",4
copymemory byval varptr(a(0)),1234,4 在 VB 中处于安全考虑,不能直接访问内存,但你可以使用 CopyMemory(RtlMoveMemory) 的 API 来复制指定区域的内存,
其具体声明如下:
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
其中,
Destination 是指向复制目标的指针,可以直接指定为某个变量或是数组(如果是数组应使用 myArray(0) 或是 myArray(n) 来指定覆盖的起点,不能直接使用 myArray),或是使用 ByVal 关键字加内存地址
Source 是复制源的指针,用法与上面一样
Length 是复制的长度,以字节为单位。 VB 6 中没有公开的三个函数:VarPtr,StrPtr,ObjPtr
它们分别返回变量、字符串、对象的指针(就是内存地址) 因此,在执行:
copymemory b(0),byval "1234",4
时,VB 会先在内存中划出一块儿区域,
用于保存值为 "1234" 的字符串,
然后把这个字符串的指针传给 CopyMemory,
CopyMemory 把内存中刚才保存字符串数据的地址处的数据复制到数组 b 中,
从 b(0) 开始覆盖,覆盖 4 个字节 VB 6 在调用 API 时,字符串一般是按值(ByVal)传递,
在传递时以 ANSI 编码。
也就是说,上面那句代码等价于(为了安全性,我个人推荐下面这种做法):
Erase b
b = StrConv("1234", vbFromUnicode) 而
copymemory byval varptr(a(0)),1234,4
其实就是
CopyMemory a(0),1234,4
在执行时,
VB 会先在内存中划出 2 个字节(1234 等价于 1234% 或是 CInt(1234))
用于保存值为 1234 的 Integer,
然后在执行 CopyMemory 时,
把内存中刚才保存有 1234 处的数据复制到数组 b 中,
从 a(0) 开始覆盖,覆盖 4 个字节。
问题是,
你把指针给人家时,只在对应的位置划了 2 个字节,
你却要人家从你给的位置读 4 个字节……
由于后两个字节没有被分配,
因此可能会返回一个任意值,
不排除崩溃的可能,
而且还是你的程序带着开发环境 IDE 一块儿崩溃。
估计你本来应该这么写(我觉得 byval varptr(...) 累赘了):
CopyMemory a(0),1234&,4
这样,划出来的就是 4 个字节(Long)了。
可是,如果是这样,那你还不如用:
a(0) = 1234
又方便,又安全…… 还有,
CopyMemory 只负责复制,不负责分配内存。
因此你在把 a、b 数组当成复制覆盖的目标之前,
至少需要分配一下内存吧(若你是在问题中省略了就算了……)
例如:
ReDim a(0) '4 x 1 = 4 字节
ReDim b(3) '1 x 4 = 4 字节
但如果你准备使用
b = StrConv("1234", vbFromUnicode)
这样的代码,
则 b 一定要是空的,如果不是,则需要使用 Erase 清空
VB 中 copymemory的有关问题的更多相关文章
- VB中 '&' 和 '+' 号的区别
释义 &(Ampersand)是英语单字and之代表符号,亦可用作中文中的“和”.“与”之代表符号.这个符号源于拉丁文的et的连写. 可读做 ampersand,即 "and per ...
- VB 中 NumericUpDown 控件 如何为手动输入设定触发事件
Private Sub numDuration_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) ...
- VB 中Sub和Function的区别
Sub可以理解为执行一个过车,一个操作. Function在执行完过后,还要返回一个结果. Sub:过程:Function:函数,可以带返回值. 语法: Sub SubName(参数1,参数2,... ...
- VB中的API详解
一.API是什么? 这个我本来不想说的,不过也许你知道其它人不知道,这里为了照顾一下新手,不得不说些废话,请大家谅解. Win32 API即为Microsoft 32位平台的应用程序编程接口(Appl ...
- VB中 ByRef与ByVal区别
函数调用的参数传递有"值传递"和"引用传递"两种传递方式.如果采用"值传递",在函数内部改变了参数的值,主调程序的对应变量的值不会改变:如果 ...
- 【转】VB中应用DDE
动态数据交换(dde)是windows应用程序间通讯的基本方法之一,在动态数据交换的过程中,提供数据和服务的应用程序称为服务器,请求数据或服务的应用程序则称为客户. dde交谈是由客户程序启动的.如果 ...
- VB中的+与&符号的区别
字符串运算符和字符串表达式 字符串运算符的作用是将两个字符串连接成一个字符串,经常形象的叫做连接符. 在VB中就提供了两种连接用的字符串运算符 “&”.“+” 例如 “VB”+“编程入门” ...
- C#中实现VB中的CreateObject方法
经常看到有些VB的例子中直接用个CreateObject就可调用系统功能(大多是COM对象),像用户设定,网络设定等等.虽然C#中可以通过使用VB的命名空间的方法来调用CreateObject函数,但 ...
- 在VB中使用Linq To SQLite注意事项
昨天使Linq To SQLite 支持VB,今天在VB中写了几条Linq语句,发现了几个问题: 1.在Linq To SQLite中的Linq语句查询后并不是得到的匿名数据类,而是将Linq转换为S ...
随机推荐
- 技术人生:Knowing when or where it’s appropriate to use a technique or tool is just as important as knowing how to use it.
Knowing when or where it’s appropriate to use a technique or tool is just as important as knowing ho ...
- Docker 常用命令与操作
介绍 此命令集合版本为 1.11.1 及以上 基础类 查看docker信息 # 查看docker版本 docker version # 显示docker系统的信息 docker info # 日志信息 ...
- MySQL 锁模式
InnoDB implements standard row-level locking where there are two types of locks, shared (S) locks an ...
- img设置默认图片最简单的解决方法
<img src='图片的路径' onerror='this.src="如果图片不存在,则使用该图片"' 这个解决方法除了简单外,还有一个优点. 就是当你不知道图片是否存在, ...
- Verilog 加法器和减法器(1)
两个一位的二进制数x,y相加,假设和为s,进位为cout,其真值表为: 从真值表中,我们可以得到:s = x^y, cout = x&y,实现两个一位数相加的逻辑电路称为半加器. 实现该电路的 ...
- go语言之进阶篇文件常用操作接口介绍和使用
一.文件常用操作接口介绍 1.创建文件 法1: 推荐用法 func Create(name string) (file *File, err Error) 根据提供的文件名创建新的文件,返回一个文件对 ...
- jQuery easyui layout布局自适应浏览器大小(转)
首先解释一下标题的含义,当我们用jQuery easyui layout 进行布局的时候,可能会遇到这样一个问题,那就是当手工调整浏览器大小,或者最大化.还原窗口的时候,layout的某个区域不能填充 ...
- 10款CSS3按钮 - 程序员再也不用为按钮设计而发愁了...
这次主要给大家分享10款风格各异的CSS3按钮,如果你希望你的页面也能有很炫的样式,那么我相信这10款CSS3按钮就非常适合你,而且每一款都整理了源代码供参考,一起来看看吧. 1.绚丽的CSS3发光按 ...
- Js组件的一些写法
首先看下Prototype里的写法: var Class = { create: function() { return function() { this.init.apply(this, argu ...
- python3 CERTIFICATE_VERIFY_FAILED错误 certificate verify failed
在response = request.urlopen(url)打开一个https连接时报如下错误: urllib.error.URLError: <urlopen error [SSL: CE ...