dim sBuffer(5) as byte ,  iShukaqiBH as long ,i as long for i=0 to 4
  sBuffer(i)=0
next iiShukaqiBH =1Call CopyMemory(sBuffer(1), iShukaqiBH, 2)CopyMemory函数执行完后,sBuffer(1)应该等于1 ,而现在的结果是等5,请问是怎么回事。

解决方案 »

  1.   

    你的 CopyMemory 声明有差异,建议装个 ApiViewer 工具
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
      

  2.   


    非常感谢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 是正确的请问,这到底是为什么呢,谢谢。还有为什么这一个函数可以有多个声明方式呢,得到的结果还不一样?
      

  3.   

    CopyMemory 是一个比较特殊的函数,原型中是用 Void 指针来适应任意的数据结构。
    正因为原型的任意性,VB 中可以通过声明中参数的变化来对应具体的数据结构。
    如果声明和应用不匹配。轻则出错,重则崩溃。要用好API,不仅基础知识要好,语言也要很精深。
      

  4.   

    谢谢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)两个声明实际上应该是完全一下的呀,为什么结果会有两个呢?
      

  5.   

    在我这里两个声明的运行结果是一样的!主要差别是声明1中 LibName 没有后缀 .dll,可能系统环境有关。64位系统?
      

  6.   


    kernel32.dll 这不是一个系统文件吗,调用这个COPYMEMORY函数时,不从kernel32.dll中调用,还能到其他的文件比如kernel32.ccc中调用吗,不可能吧
      

  7.   

    刚又试了一下:(声明1中 加 上  ".dll")
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)得到的结果还是结果还是5
      

  8.   


    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    又试了一下,返回的结果也是5,也是错误的,看来是不稳定,到底是怎么回事呢?CopyMemory 真不敢用了。
      

  9.   

    我在机上试了一下,结果:sBuffer(1)应该等于1,正常
    我机上的声明是这样的
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
      

  10.   


    最新研究结果如下:完整的代码如下:
    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 属性有关系?
      

  11.   

    我测试的结果,没有任何差别。微软提供的 API Viewer 给出的就是:Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
      

  12.   


    最新研究结果如下:完整的代码如下:
    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 属性有关系? 
      

  13.   

    你认为 iShukaqiBH 肯定是 1,所以怀疑 CopyMmemory 结果不对?
      

  14.   


    经测试结果是1
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Sub Command1_Click()
        Dim sBuffer(5) As Byte, iShukaqiBH As Long, i As Long
        
        For i = 0 To 4
          sBuffer(i) = 0
        Next i
        
        iShukaqiBH = 1
        
        Call CopyMemory(sBuffer(1), iShukaqiBH, 2)
        
        Print sBuffer(1)
    End Sub
      

  15.   

    kernel32 是什么
      

  16.   


    在执行Call CopyMemory(sBuffer(1), iShukaqiBH, 2)前,每次都查看过了,iShukaqiBH是等于1呀。sBuffer(1)没有理由为5呀。
      

  17.   

    其实要搞清你的疑问的最简单直接的方法,就是用你开贴的代码去测试,而不是什么完整代码。当然,在你要确定最终问题出在哪里的时候,不妨在 Call CopyMemory(sBuffer(1), iShukaqiBH, 2) 语句之前,加上一句 Debug.Print iShukaqiBH。Debug 就是要测试,不能拍脑袋,更不能拍胸脯。
      

  18.   


    最新研究结果如下:完整的代码如下:
    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 属性有关系?Optional ByVal iShukaqiBH as long= 65535
    Call CopyMemory(sBuffer(1),byval iShukaqiBH, 4)