Updated Please see the last part of the question for updates
Full source-code here:
https://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=30761&lngWId=1
I have a piece of code that does not work, probably due to 32-bit and 64-bit difference:
Part of the code: (I added the PtrSafe, which I shouldn't for the first one)
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
I googled for sometime, found out that msvbvm60.dll seems to be the old 32-bit VBA and has been replaced with VBA7.dll. Tried to re-register the file as it is in SysWOW64 folder, after which VBE still reports that cannot find this file. So I commented the first line, and changed the last line to:
RtlMoveMemory ByVal VarPtr(SafeArray1), VarPtr(Header1(0)), 4
As I believe ArrPtr is simply VarPtr with an alias.
Now I get a type mismatch error. What I understand is that the code points the header of SafeArray1 to the address of Header1(0). I assume that it means that SafeArray1[0]~SafeArray[9] should contain the info in Header1(0)~Header1(4) as Header1() is Long and SafeArray() is Integer? But shouldn't VarPtr returns Long in 32-bit Office and how come it is possible to use it on an Integer array?
But the point is how to make it run on 64-bit Office. Since VarPtr now returns LongPtr instead of Long, I'm not sure how to modify the code.
Updates I found another piece of code that gives me pointer to an array:
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (ByRef Var() As Any) As LongPtr
Then I write a test module:
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
But VBE crashes on the RtlMoveMemory line.
The following example should show how to handle Declare
statement for 32 and 64 bit versions:
Option Explicit
#If VBA7 Then '64 bit
Private Declare PtrSafe Function DrawMenuBar Lib "User32" (ByVal hwnd As LongPtr) As LongPtr
#Else '32 bit
Private Declare Function DrawMenuBar Lib "User32" (ByVal hwnd As Long) As Long
#End If
on the crash issue, I noticed this line:
RtlMoveMemory ByVal VarPtrArray(SafeArray1), VarPtr(Header1(0)), 4
The last argument should be "long" as declared, so try to put "4" in a long variable and pass it to the function. This is my workaround for my own similar case, and hope that helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.