Results 1 to 2 of 2

Thread: VBA7 64-bit Array of Variants Overlay Problem

  1. #1

    Thread Starter
    New Member
    Join Date
    Aug 2015
    Posts
    7

    VBA7 64-bit Array of Variants Overlay Problem

    I have used Olaf's fantastic code successfully for a long time now... but in Excel VBA, 32bit.

    I now need to use it in VBA7, 64bit and it seems no matter how I modify it the code either won't compile or if it does, it crashes Excel.

    I'm aware of the normal things to do to port 32bit VBA code to 64bit, but I think that utilizing the Type SAFEARRAY1D throws a wrench in the mix.

    I definitely need to overlay an existing array and temporarily access it from a second variable. Again, this has been working for me for years in 32bit VBA, but I'm missing something to get it working in 64bit VBA.

    And I realize I need to ReleaseArray when done. That is not the problem. My ported code does not get that far.

    I need the code to run successfully in both Excel VBA environments, 32bit and 64bit.

    Here is a small sample of code that demonstrates the problem...



    Code:
    Option Explicit
    
    Private Type SAFEARRAY1D
      cDims As Integer
      fFeatures As Integer
      cbElements As Long
      cLocks As Long
      pvData As Long        '<-- This cannot be LongLong, can it?
      cElements1D As Long
      lLbound1D As Long
    End Type
    
    
    #If VBA7 Then
        Private Declare PtrSafe Sub BindArray Lib "kernel32" Alias "RtlMoveMemory" (PArr() As Any, pSrc As LongPtr, Optional ByVal CB& = 8)
        Private Declare PtrSafe Sub ReleaseArray Lib "kernel32" Alias "RtlMoveMemory" (PArr() As Any, Optional pSrc As LongPtr = 0, Optional ByVal CB& = 8)
    #Else
        Private Declare Sub BindArray Lib "kernel32" Alias "RtlMoveMemory" (PArr() As Any, pSrc&, Optional ByVal CB& = 4)
        Private Declare Sub ReleaseArray Lib "kernel32" Alias "RtlMoveMemory" (PArr() As Any, Optional pSrc& = 0, Optional ByVal CB& = 4)
    #End If
    
    Private W() As Integer, saW As SAFEARRAY1D
    
    
    Sub TEST()
    
        Dim v()
        ReDim v(0 To 9)
    
        saW.cDims = 1
        saW.cbElements = 2
        saW.cbElements = 16        '<-- Should this be 24 for array of variants in 64bit???
        saW.pvData = VarPtr(v(0))  '<-- VarPtr(v(0)) produces a type mismatch error. VarPtr in 64bit VBA returns LongLong, but saW.pvData needs a 32bit pointer.
        BindArray W, VarPtr(saW)
    
    End Sub

    Thank you very much.
    Last edited by xyrph; Jun 11th, 2020 at 11:16 AM.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: VBA7 64-bit Array of Variants Overlay Problem

    Quote Originally Posted by xyrph View Post
    pvData As Long '<-- This cannot be LongLong, can it?
    This member is clearly a pointer, so it should use the 8Bytes long VBA-64-PointerType.

    Quote Originally Posted by xyrph View Post
    Private W() As Integer, saW As SAFEARRAY1D
    The 'W()' above was intended to be spanned across a (V)BSTR.
    If that's still your intention, then leave it as it is...

    But if you want it to be mapped as a Variant-Array, you should tell the VBA-compiler about it.

    Quote Originally Posted by xyrph View Post
    saW.cbElements = 16 '<-- Should this be 24 for array of variants in 64bit???
    If in doubt, just use the LenB-function for that - e.g. this way:
    saW.cbElements = LenB(W(0))

    HTH

    Olaf

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width