CopyMemory вылетает в Excel, если не вставлен в функцию - PullRequest
0 голосов
/ 29 мая 2018

Я столкнулся со странной проблемой при экспериментировании с CopyMemory.У меня есть один фрагмент кода, скопированный из Bytecomb , который работает, только если я помещаю его в функцию:

Я ставлю это в начале:

Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)

Рабочая версия:

Sub StringTest()
    Dim str1 As String
    Dim pstr1 As LongPtr

    str1 = "PowerVB"
    Debug.Print "Memory  : 0x"; Mem_ReadHex(pstr1 - 4, LenB(str1) + 6)

End Sub

Public Function Mem_ReadHex(ByVal Ptr As LongPtr, ByVal Length As Long) As String
    Dim bBuffer() As Byte, strBytes() As String, i As Long, ub As Long, b As Byte
    ub = Length - 1
    ReDim bBuffer(ub)
    ReDim strBytes(ub)
    CopyMemory bBuffer(0), ByVal Ptr, Length
    For i = 0 To ub
        b = bBuffer(i)
        strBytes(i) = IIf(b < 16, "0", "") & Hex$(b)
    Next
    Mem_ReadHex = Join(strBytes, "")
End Function

Эта программа прекрасно распечатывает весь макет строки в памяти (сначала 4 байта указывают длину, затем содержимое строки, а затем 2 байта с нулем):

Memory  : 0x0E00000050006F00770065007200560042000000

Теперь происходит сбой, если я помещаю функцию в подпрограмму:

Sub StringTest()
    Dim str1 As String
    Dim str2 As String
    Dim pstr1 As LongPtr

    str1 = "PowerVB"
    CopyMemory pstr1, ByVal VarPtr(str1), 8

    Dim bBuffer() As Byte, strBytes() As String
    ub = LenB(str1) + 5
    ReDim bBuffer(ub)
    ReDim strBytes(ub)
    CopyMemory bBuffer(0), ByVal pstr1 - 4, LenB(str1) + 6 'extra 4 bytes for string length, and 2 bytes of null characters
    For i = 0 To ub
        b = bBuffer(i)
        strBytes(i) = IIf(b < 16, "0", "") & Hex$(b) 'for 2 bytes, if the value < 16, then it only consists of one byte
    Next i
    Debug.Print Join(strBytes, "")
End Sub

Я не понимаю.В чем разница между двумя версиями?

1 Ответ

0 голосов
/ 29 мая 2018

ОК. Я нашел исправление:

CopyMemory bBuffer(0), ByVal pstr1 - 4, ub + 1

Поскольку CopyMemory должен принимать long в качестве третьего параметра, я не могу использовать LenB(str1) + 6, поскольку это, вероятно, целое число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...