了解RtlMoveMemory

问题描述 投票:2回答:1

感谢您阅读本文。我出于好奇而试图理解这一点。我从某个地方复制了这段代码,试着乱七八糟但却无法按预期工作。我希望Debug.Print c返回4,但它保持3.我怀疑错误可能是数据类型但不确定,因为没有错误弹出。

Option Explicit

#If VBA7 Then
    Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias _
            "RtlMoveMemory" (ByRef Destination As LongPtr, ByRef Source As LongPtr, _
            ByVal Length As LongPtr)
#Else
    Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias _
           "RtlMoveMemory" (Destination As Long, Source As Long, _
            ByVal Length As Long)
#End If

Sub Main2()
    Dim c As Long, d As Long

    c = 3
    Move2 VarPtr(c)
    Debug.Print c

End Sub

Sub Move2(ByVal pointerOfi As LongPtr)
    Dim tempvalue As Long

    CopyMemory VarPtr(tempvalue), pointerOfi, LenB(pointerOfi)
    tempvalue = tempvalue + 1
    CopyMemory pointerOfi, VarPtr(tempvalue), LenB(pointerOfi)

End Sub
vba
1个回答
2
投票

您对CopyMemory参数的声明不包括ByVal关键字,因此所有参数都通过引用传递(ByRef),这意味着:

CopyMemory VarPtr(tempvalue), pointerOfi, LenB(pointerOfi)

CopyMemory传递了2个长值的引用(地址),这两个长值是评估VarPtr(tempvalue)pointerOfi的结果,而不是这些变量包含的实际值。

如果你有一个包含内存地址的变量,那么你需要传递值本身而不是包含值的变量的地址:

CopyMemory ByVal VarPtr(tempvalue), ByVal pointerOfi, LenB(pointerOfi)

请注意,您可以利用ByRef而不用担心原始指针:

Sub Main2()
    Dim c As Long, d As Long

    c = 3
    Move2 c
    Debug.Print c
End Sub

Sub Move2(x As Long)
    Dim tempvalue As Long

    CopyMemory tempvalue, x, LenB(tempvalue)
    tempvalue = tempvalue + 1
    CopyMemory x, tempvalue, LenB(x)
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.