非常奇怪的CopyMemory的问题
dim sBuffer(5) as byte , iShukaqiBH as long ,i as longfor i=0 to 4
sBuffer(i)=0
next i
iShukaqiBH =1
Call CopyMemory(sBuffer(1), iShukaqiBH, 2)
CopyMemory函数执行完后,sBuffer(1)应该等于1 ,而现在的结果是等5,请问是怎么回事。
--------------------编程问答-------------------- 你的 CopyMemory 声明有差异,建议装个 ApiViewer 工具
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)--------------------编程问答--------------------
非常感谢
1、当声明为:Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)时 sBuffer(1)结果为5 是错误的
2、当声明为:Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) 时 sBuffer(1)结果为1 是正确的
请问,这到底是为什么呢,谢谢。还有为什么这一个函数可以有多个声明方式呢,得到的结果还不一样?
--------------------编程问答-------------------- CopyMemory 是一个比较特殊的函数,原型中是用 Void 指针来适应任意的数据结构。
正因为原型的任意性,VB 中可以通过声明中参数的变化来对应具体的数据结构。
如果声明和应用不匹配。轻则出错,重则崩溃。
要用好API,不仅基础知识要好,语言也要很精深。 --------------------编程问答-------------------- 谢谢Tiger_Zhao ,但是还是要麻烦再问一下:
因为VB6 中默认是使用 ByRef 来传递参数,所以
声明1、:Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
声明2、:Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
两个声明实际上应该是完全一下的呀,为什么结果会有两个呢?
--------------------编程问答-------------------- 在我这里两个声明的运行结果是一样的!
主要差别是声明1中 LibName 没有后缀 .dll,可能系统环境有关。64位系统? --------------------编程问答--------------------
不是,是32位XP --------------------编程问答--------------------
不过这能有什么区别吗?
--------------------编程问答-------------------- 我这里没区别。
你那里偏偏有区别,有什么库叫 kernel32。病毒?外挂? --------------------编程问答--------------------
kernel32.dll 这不是一个系统文件吗,调用这个COPYMEMORY函数时,不从kernel32.dll中调用,还能到其他的文件比如kernel32.ccc中调用吗,不可能吧 --------------------编程问答-------------------- 刚又试了一下:(声明1中 加 上 ".dll")
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
得到的结果还是结果还是5 --------------------编程问答-------------------- 只能从环境上找问题咯。
断网。
关各种反病毒、反木马工具。
关各种界面美化、翻译工具。
关各种程序。
VB-IDE 中取消各种 Add-in 的加载。
新开工程测试。 --------------------编程问答--------------------
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
又试了一下,返回的结果也是5,也是错误的,看来是不稳定,到底是怎么回事呢?CopyMemory 真不敢用了。
--------------------编程问答-------------------- 你的系统不能用才是真的! --------------------编程问答-------------------- 我在机上试了一下,结果:sBuffer(1)应该等于1,正常
我机上的声明是这样的
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) --------------------编程问答--------------------
最新研究结果如下:
完整的代码如下:
Public Function SendSKQ(ByVal iBiaohao As Long, ByVal ihuhao As Integer, Optional ByVal iShukaqiBH = 65535) As Integer
Dim sql As String, rs As New ADODB.Recordset
' 当iShukaqiBH 为65535的值时, iShukaqiBH 从数据库中提取
If iShukaqiBH = 65535 Then
sql = " select 刷卡器编号 from yhxx where 表号= " & iBiaohao & " and 户号= " & ihuhao & ""
rs.Open sql, Conn, adOpenKeyset, adLockReadOnly
If rs.RecordCount > 0 Then
iShukaqiBH = Val(rs.Fields("刷卡器编号"))
else
iShukaqiBH=1
end if
End If
Dim sBuffer(8) As Byte
For i = 0 To 7
sBuffer(i) = 0
Next i
’ 1、的内容开始*****************************
Call CopyMemory(sBuffer(1), iShukaqiBH, 2) ' sBuffer(1), 结果为5
’ 1、的内容结束********************************
'如果按2来执行 sBuffer(1) 结果是正常的为1
’2的内容如下 开始***************************************
Dim sShukaqiBH As Long
sShukaqiBH = iShukaqiBH
Call CopyMemory(sBuffer(1), sShukaqiBH, 2)
'2的内容结束 ********************************************
End function
这个问题是不是根iShukaqiBH这个参数的optional 属性有关系? --------------------编程问答-------------------- 我测试的结果,没有任何差别。
微软提供的 API Viewer 给出的就是:
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)--------------------编程问答-------------------- --------------------编程问答-------------------- 你认为 iShukaqiBH 肯定是 1,所以怀疑 CopyMmemory 结果不对?
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- kernel32 是什么。。。 --------------------编程问答--------------------
在执行Call CopyMemory(sBuffer(1), iShukaqiBH, 2)前,每次都查看过了,iShukaqiBH是等于1呀。
sBuffer(1)没有理由为5呀。 --------------------编程问答-------------------- 其实要搞清你的疑问的最简单直接的方法,就是用你开贴的代码去测试,而不是什么完整代码。
当然,在你要确定最终问题出在哪里的时候,不妨在 Call CopyMemory(sBuffer(1), iShukaqiBH, 2) 语句之前,加上一句 Debug.Print iShukaqiBH。
Debug 就是要测试,不能拍脑袋,更不能拍胸脯。
--------------------编程问答--------------------
Optional ByVal iShukaqiBH as long= 65535
Call CopyMemory(sBuffer(1),byval iShukaqiBH, 4)
补充:VB , 基础类