Results 1 to 40 of 119

Thread: CopyMemory Function

Threaded View

  1. #11

    Thread Starter
    Lively Member
    Join Date
    Jun 2009
    Posts
    83

    Re: CopyMemory Function

    What do you think, for instance, about the below? Is it dangerous, inefficient, or what? (I've made the input and output of the OverlayStr function variant because I want to build it up so it can handle strings, doubles, and genuine variants).

    Edit: Actually, it's far from safe, so don't run it without saving your work! But I'm not sure quite why...

    Code:
    Option Explicit
    Public pLB1 As Long, pUB1 As Long
    Public pLB2 As Long, pUB2 As Long
    Public pnElmts As Long
    Private Type SABnd
        nElmts As Long
        nLBnd As Long
    End Type
    Private Type SafeArr          'http://msdn.microsoft.com/en-us/library/ms221482.aspx
        nDims As Integer          'ArrayPtr +0: number of dimensions
        fFlags As Integer         '         +2: see link
        nBytes As Long            '         +4: number of bytes per array item
        nLocks As Long            '         +8: whether or not array is locked
        nPtrTo1stElmt As Long     '        +12: pointer to first element in array
        nBnds(0 To 1) As SABnd    '        +16: pointer to last dim's count & LBound structure
    End Type                      '             stored in right to left order
    Sub SetBndVars(v As Variant)
       pLB2 = -1: pUB2 = -1
       pLB1 = LBound(v, 1): pUB1 = UBound(v, 1)
       On Error Resume Next
          pLB2 = LBound(v, 2): pUB2 = UBound(v, 2)
       On Error GoTo 0
       If pLB1 < pUB1 Or pLB2 = -1 Then
          pnElmts = pUB1 - pLB1 + 1
       Else
          pnElmts = pUB2 - pLB2 + 1
       End If
    End Sub
    Sub TestStr()
       Dim s() As String
       ReDim s(0 To 10, 1 To 1)
       Dim i As Long
          For i = 0 To 10
             s(i, 1) = "ZZZZZZZZ"
          Next i
       Dim sRes() As String
       sRes = OverlayStr(s)
    End Sub
    Function OverlayStr(v As Variant) As Variant
       SetBndVars v
       Dim LngOverlay() As Long
       Dim vPtr As Long
       'Let vPtr be the location of the [long] pointer in the variant
       CopyMemory vPtr, ByVal VarPtr(v) + 8&, 4&
       'Find out where that pointer is pointing to:
       CopyMemory vPtr, ByVal vPtr, 4&
       '...and this is where we put the overlay, so
       Dim SA As SafeArr
       With SA                                            'i.e. the new array description
          .nBytes = 4                                     'bytes per array item
          .nDims = 1                                      'number of dimensions
          CopyMemory .nPtrTo1stElmt, ByVal vPtr + 12&, 4& 'location of 1st element in array
          .nBnds(0).nElmts = pnElmts
          .nBnds(0).nLBnd = 1
       End With
       CopyMemory ByVal VarPtrArray(LngOverlay), VarPtr(SA), 4&
       Dim s() As String
       ReDim s(1 To UBound(LngOverlay))
       CopyMemory ByVal VarPtr(s(1)), LngOverlay(1), 4& * UBound(LngOverlay)
       OverlayStr = s
       CopyMemory ByVal VarPtrArray(LngOverlay), 0&, 4& ' release overlay
       ZeroMemory ByVal vPtr + 12&, 4& * UBound(s)
    End Function
    Last edited by James_B; Jul 31st, 2009 at 11:36 AM. Reason: As per the suggestion in post 83

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