API函数,多用了一组括号怎么就不一样那

王二.麻子 2011-04-25 03:29:04
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, Optional ByVal Length As Long = 4)

Private Sub Form_Load()
Dim a(10) As Byte, i, b As Integer, c As Long
For i = 0 To 10
a(i) = i
Next i
Debug.Print Hex(a(2)), Hex(a(1)) '源
CopyMemory b, a(1), 2& '内存复制
Debug.Print Hex(b) '内存复制后

Debug.Print Hex(a(4)), Hex(a(3)), Hex(a(2)), Hex(a(1)) '源
CopyMemory c, a(1), 4& '内存复制
Debug.Print Hex(c) '内存复制后

Debug.Print Hex(a(2)), Hex(a(1)) '源
CopyMemory b, (a(1)), 2& '内存复制,多用了括号
Debug.Print Hex(b) '内存复制后

Debug.Print Hex(a(4)), Hex(a(3)), Hex(a(2)), Hex(a(1)) '源
CopyMemory c, (a(1)), 4& '内存复制,多用了括号
Debug.Print Hex(c) '内存复制后

End Sub


运行结果

2 1'复制前
201'复制后
4 3 2 1'复制前
4030201'复制后
2 1'复制前
1'复制后
4 3 2 1'复制前
1'复制后


为什么多用了括号,复制的结果就不同那。
...全文
140 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
嗷嗷叫的老马 2011-04-26
  • 打赏
  • 举报
回复
AAA (x), (x)
//
由于第一个参数是BYREF,所以把保存(X)结果的临时变量的地址传进去了,这个临时变量类型为LONG,值与X相同.

不用括号,则按BYREF,把X的地址传进去了.
神马都能聊 2011-04-26
  • 打赏
  • 举报
回复
不用(),传递方式按照调用者的传递方式运行,除非你指定传递方式。比如整型默认Byval,字符串默认Byref,VB6大部分时候是按照Byref传递的,经常存在内部类型转换。

用了(),传递方式按照被调用者的传递方式运行。

参数传递方式宝书(高级VB编程)里有介绍,前面的部分并不是很难懂。
王二.麻子 2011-04-26
  • 打赏
  • 举报
回复
Quote=引用 9 楼 myjian 的回复:]
简单来说:

ByRef As Any = 传入任何东西都取它的地址为参数.

ByVal As [确定的类型] = 传入任何东西都转换为已指定的类型,并取它的值作为参数.
[/Quote]

[Quote=引用 11 楼 veron_04 的回复:]
http://download.csdn.net/source/1681799
[/Quote]
我没那么多的分来下载,可怜

Option Explicit
Dim x As Long

Function AAA(ByRef xx As Long, ByVal yy As Long) As Long
Debug.Print "直接使用", xx, yy
Debug.Print "参数地址", VarPtr(xx), VarPtr(yy)
End Function
Private Sub Form_Load()
x = 1
Debug.Print "全局变量,地址,值", VarPtr(x), x
Debug.Print "没有用()"
AAA x, x
Debug.Print "用()"
AAA (x), (x)
End Sub

结果:
全局变量,地址,值           1562396       1 
没有用()
直接使用 1 1
参数地址 1562396 1308832
用()
直接使用 1 1
参数地址 1308844 1308832

在vb里面,窗体变量的地址,和过程中的变量的地址,差别是很大的,过程中的变量其地址是在堆栈里面

所以变量x的地址和参数xx,yy的地址是有差别的。

没有使用(),就byref传递的是参数地址,
byval传递的是参数的值,在堆栈临时分配空间,放这个参数,把这个临时分配的参数传递过去

使用()后,byref类型的传递,就先计算()中的表达式的值,然后在堆栈中临时分配空间,存放结果,然后吧结果的地址做参数传递过去,而byval依然在堆栈临时分配空间,存值,传递堆栈的这个参数

这样和AisaC说的差不多。

在某些时候,给参数加()可以有难于察觉的效果,哈哈
嗷嗷叫的老马 2011-04-26
  • 打赏
  • 举报
回复
别人不像我一样闲
王二.麻子 2011-04-26
  • 打赏
  • 举报
回复
结了吧,没啥人。
贝隆 2011-04-25
  • 打赏
  • 举报
回复
lxq19851204 2011-04-25
  • 打赏
  • 举报
回复
我是来向老马学习的~~
嗷嗷叫的老马 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 spt_petrolor 的回复:]
你的意思是,vb临时分配了一个变量ltemp(应该是在堆栈里面吧),然后用这个变量的地址做参数,调用了copymemory?
而用byval则告诉vb,这里是个地址,不需要分配临时变量了,就用这个值去做参数调用copymemory?

是不是可以在这里弄个shellcode,把返回地址给干掉,跑到shellcode里面去?


引用 5 楼 myjian 的回复:
少了一句.....……
[/Quote]
简单来说:

ByRef As Any = 传入任何东西都取它的地址为参数.

ByVal As [确定的类型] = 传入任何东西都转换为已指定的类型,并取它的值作为参数.
神马都能聊 2011-04-25
  • 打赏
  • 举报
回复
把代码复制到IDE内,是可执行的,去掉括号就不能执行。
王二.麻子 2011-04-25
  • 打赏
  • 举报
回复
你的意思是,vb临时分配了一个变量ltemp(应该是在堆栈里面吧),然后用这个变量的地址做参数,调用了copymemory?
而用byval则告诉vb,这里是个地址,不需要分配临时变量了,就用这个值去做参数调用copymemory?

是不是可以在这里弄个shellcode,把返回地址给干掉,跑到shellcode里面去?

[Quote=引用 5 楼 myjian 的回复:]
少了一句.........ltmp=&H9999
[/Quote]
王二.麻子 2011-04-25
  • 打赏
  • 举报
回复
没效果。。。byref参数类型不符
[Quote=引用 3 楼 aisac 的回复:]
一个是传的表达式,一个传的不是表达式。

Sub Call_MyFunc()
Dim intX As Long
intX = 10 * 3
MyFunc (intX)'你可以去掉此处的()试试看效果.
End Sub

Sub MyFunc(sParam As String)
Debug.Print sParam 'sParam 的值为字符串 30
End Su……
[/Quote]
嗷嗷叫的老马 2011-04-25
  • 打赏
  • 举报
回复
少了一句.........ltmp=&H9999
嗷嗷叫的老马 2011-04-25
  • 打赏
  • 举报
回复
不是.

加了括号,就是等于写了一个直接数进去.

而因为BYREF的存在,会取这个直接数的地址传进去.

所以:

copymoney c,&H9999,4&

就等于:

dim lTmp as long '临时变量

copymoney c,lTmp,4&
神马都能聊 2011-04-25
  • 打赏
  • 举报
回复
一个是传的表达式,一个传的不是表达式。

Sub Call_MyFunc()
Dim intX As Long
intX = 10 * 3
MyFunc (intX)'你可以去掉此处的()试试看效果.
End Sub

Sub MyFunc(sParam As String)
Debug.Print sParam 'sParam 的值为字符串 30
End Sub
王二.麻子 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 myjian 的回复:]
看声明,是BYREF,所以加了括号后,是把括号中表达式的值的地址传进去了.
[/Quote]
那多加一组括号,就相当与byval了。
嗷嗷叫的老马 2011-04-25
  • 打赏
  • 举报
回复
看声明,是BYREF,所以加了括号后,是把括号中表达式的值的地址传进去了.

7,765

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧