CopyMemory, Variants and Byte Arrays


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: CopyMemory, Variants and Byte Arrays

  1. #1
    Doug Neary Guest

    CopyMemory, Variants and Byte Arrays

    Hi All:

    Searching Deja didn't turn up anything, so I thought I'd try here.

    I'm being passed a Variant which contains an array of bytes. I need to
    break it into 3 pieces, looping is slow, and CopyMemory seems ideal. I
    can't seem to get a pointer to the data in the variant.

    The following code illustrates my problem...

    Option Explicit
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    (Destination As Any, Source As Any, ByVal Length As Long)

    Sub Test()
    Dim bytSource(0 To 3) As Byte
    Dim bytDest(0 To 3) As Byte
    Dim varTest As Variant

    'load up some test data
    bytSource(0) = 0
    bytSource(1) = 1
    bytSource(2) = 2
    bytSource(3) = 3

    'this creates a variant of subtype byte array (8209 according to vartype)
    varTest = bytSource

    'this works just fine, you can look at the bytes in the locals window
    CopyMemory bytDest(0), bytSource(0), 4

    'none of the following work
    CopyMemory bytDest(0), varTest(0), 4
    CopyMemory bytDest(0), VarPtr(varTest(0)), 4
    CopyMemory bytDest(0), ByVal (VarPtr(varTest(0))), 4

    End Sub

    Any help would be appreciated.

    --D



  2. #2
    Jonathan Wood Guest

    Re: CopyMemory, Variants and Byte Arrays

    Doug,

    There are a number of things happening here. First, a Variant is actually a
    structure. For most data types, the Variant data actually begins 8 bytes
    into the array. (Be sure to verify the Variant is of the correct type before
    attempting to access this data directly.) Second, this data in the Variant
    will be a pointer to a SAFEARRAY, rather than the data itself. Accessing the
    data of a SAFEARRAY is most safely done through the API.

    Below is an example.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com

    Option Explicit

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function SafeArrayAccessData Lib "Oleaut32" (ByVal psa As
    Long, pvData As Long) As Long
    Private Declare Function SafeArrayUnaccessData Lib "Oleaut32" (ByVal psa As
    Long) As Long

    Sub Test()
    Dim bytSource(0 To 3) As Byte
    Dim bytDest(0 To 3) As Byte
    Dim varTest As Variant
    Dim psa As Long 'Pointer to SAFEARRAY
    Dim hr As Long 'HRESULT
    Dim pData As Long

    'load up some test data
    bytSource(0) = 0
    bytSource(1) = 1
    bytSource(2) = 2
    bytSource(3) = 3

    'this creates a variant of subtype byte array (8209 according to
    vartype)
    varTest = bytSource

    'WARNING: You need to make sure Variant contains what is expected
    If TypeName(varTest) = "Byte()" Then
    'Obtain the variant data (a SAFEARRAY in our case)
    CopyMemory psa, ByVal VarPtr(varTest) + 8, 4
    'Now obtain a pointer to the array data
    hr = SafeArrayAccessData(psa, pData)
    'If function succeeded
    If hr = 0 Then
    'WARNING: This code assumes at least 4 bytes of data
    'You should verify this first
    CopyMemory bytDest(0), ByVal pData, 4
    'Release lock on SAFEARRAY
    hr = SafeArrayUnaccessData(psa)
    End If
    End If

    Debug.Print bytDest(0)
    Debug.Print bytDest(1)
    Debug.Print bytDest(2)
    Debug.Print bytDest(3)
    End Sub




  3. #3
    Jonathan Wood Guest

    Re: CopyMemory, Variants and Byte Arrays

    Doug,

    There are a number of things happening here. First, a Variant is actually a
    structure. For most data types, the Variant data actually begins 8 bytes
    into the array. (Be sure to verify the Variant is of the correct type before
    attempting to access this data directly.) Second, this data in the Variant
    will be a pointer to a SAFEARRAY, rather than the data itself. Accessing the
    data of a SAFEARRAY is most safely done through the API.

    Below is an example.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com

    Option Explicit

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function SafeArrayAccessData Lib "Oleaut32" (ByVal psa As
    Long, pvData As Long) As Long
    Private Declare Function SafeArrayUnaccessData Lib "Oleaut32" (ByVal psa As
    Long) As Long

    Sub Test()
    Dim bytSource(0 To 3) As Byte
    Dim bytDest(0 To 3) As Byte
    Dim varTest As Variant
    Dim psa As Long 'Pointer to SAFEARRAY
    Dim hr As Long 'HRESULT
    Dim pData As Long

    'load up some test data
    bytSource(0) = 0
    bytSource(1) = 1
    bytSource(2) = 2
    bytSource(3) = 3

    'this creates a variant of subtype byte array (8209 according to
    vartype)
    varTest = bytSource

    'WARNING: You need to make sure Variant contains what is expected
    If TypeName(varTest) = "Byte()" Then
    'Obtain the variant data (a SAFEARRAY in our case)
    CopyMemory psa, ByVal VarPtr(varTest) + 8, 4
    'Now obtain a pointer to the array data
    hr = SafeArrayAccessData(psa, pData)
    'If function succeeded
    If hr = 0 Then
    'WARNING: This code assumes at least 4 bytes of data
    'You should verify this first
    CopyMemory bytDest(0), ByVal pData, 4
    'Release lock on SAFEARRAY
    hr = SafeArrayUnaccessData(psa)
    End If
    End If

    Debug.Print bytDest(0)
    Debug.Print bytDest(1)
    Debug.Print bytDest(2)
    Debug.Print bytDest(3)
    End Sub




  4. #4
    Doug Neary Guest

    Re: CopyMemory, Variants and Byte Arrays

    Hi Jonathan:

    Many thanks, I figured there was something more going on here than met the
    eye.

    Thanks again.

    --D




  5. #5
    Doug Neary Guest

    Re: CopyMemory, Variants and Byte Arrays

    Hi Jonathan:

    Many thanks, I figured there was something more going on here than met the
    eye.

    Thanks again.

    --D




Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center