Обновлено См. Последнюю часть вопроса об обновлениях
Полный исходный код здесь:
https://www.planet -source-code.com/vb/scripts/ShowCode.asp?txtCodeId=30761&lngWId=1
У меня есть фрагмент кода, который не работает, вероятно, из-за 32-разрядной и 64-разрядной разницы:
Часть кода: (я добавил PtrSafe, который я не должен был для первого)
Private Declare PtrSafe Function ArrPtr& Lib "msvbvm60.dll" Alias "VarPtr" (ptr() As Any)
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes&)
Private Header1(5) As Long
Private Header2(5) As Long
Private SafeArray1() As Integer
Private SafeArray2() As Integer
Private LUT(8482) As Long
Private Sub Class_Initialize()
Dim i As Long
' Set up our template for looking at strings
Header1(0) = 1 ' Number of dimensions
Header1(1) = 2 ' Bytes per element (integer = 2)
Header1(4) = &H7FFFFFFF ' Array size, 2.1+ billion should cover us
' Force SafeArray1 to use Header1 as its own header
RtlMoveMemory ByVal ArrPtr(SafeArray1), VarPtr(Header1(0)), 4
Я гуглил некоторое время, обнаружил, что msvbvm60.dll, кажется, старый 32-бит VBA и был заменен на VBA7.dll.Попытался перерегистрировать файл, как он есть в папке SysWOW64, после чего VBE все еще сообщает, что не может найти этот файл.Поэтому я прокомментировал первую строку и изменил последнюю строку на:
RtlMoveMemory ByVal VarPtr(SafeArray1), VarPtr(Header1(0)), 4
Поскольку я считаю, что ArrPtr - это просто VarPtr с псевдонимом.
Теперь я получаю ошибку несоответствия типов.Я понимаю, что этот код указывает заголовок SafeArray1 на адрес Header1 (0).Я предполагаю, что это означает, что SafeArray1 [0] ~ SafeArray [9] должен содержать информацию в Header1 (0) ~ Header1 (4), поскольку Header1 () - Long, а SafeArray () - Integer?Но разве VarPtr не должен возвращать Long в 32-битном Office и почему его можно использовать в массиве Integer?
Но дело в том, как заставить его работать в 64-битном Office.Поскольку VarPtr теперь возвращает LongPtr вместо Long, я не уверен, как изменить код.
Обновления Я нашел другой фрагмент кода, который дает мне указатель на массив:
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (ByRef Var() As Any) As LongPtr
Затем я пишу тестовый модуль:
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (ByRef Var() As Any) As LongPtr
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes&)
Private Header1(5) As Long
Private SafeArray1() As Integer
Sub test()
Header1(0) = 1 ' Number of dimensions
Header1(1) = 2 ' Bytes per element (integer = 2)
Header1(4) = &H7FFFFFFF ' Array size, 2.1+ billion should cover us
RtlMoveMemory ByVal VarPtrArray(SafeArray1), VarPtr(Header1(0)), 4
Debug.Print SafeArray1(0)
End Sub
Но VBE дает сбой в строке RtlMoveMemory.