Can anyone please tell me how to copy the safearray returned in Variant as OLEVARIANT from the IOLECOMMANDTarget.Exec, here is what I did and it works fine except only one step explained in the code below:

I am using this:


VB Code:
  1. Dim varIn As Variant
  2. Dim varOut As Variant
  3.  
  4. 'Here I execute the command to get block formats and it returns an OLE Variant with a pointer to safearray
  5.  
  6. IOLECoammndTarget.Exec IDM_GETBLOCKFMTS, OLECMDEXECOPT_DONTPROMPTUSER, varIn, varOut


Here is my sub to parse the OLE Variant array returned which points to safearray.

VB Code:
  1. Public Sub ParseOleVariantArray(varArray As Variant, Elements() As String)
  2. '
  3. ' Given a stream of bytes that represent a Microsoft SafeArray, wade through
  4. 'the garbage and get the actual data found in the array.  Write the data to disk.
  5.  
  6. '      SafeArray looks like
  7. 'typedef struct FARSTRUCT tagSAFEARRAY {
  8. '    unsigned short cDims;           // Count of dimensions in this array.
  9. '    unsigned short fFeatures;     // Flags used by the SafeArray
  10. '                                    // routines documented below.
  11. '    unsigned long cbElements; // Size of an element of the array.
  12. '                               // Does not include size of
  13. '                               // pointed-to data.
  14. '    unsigned long cLocks;  // Number of times the array has been
  15. '    void HUGEP* pvData;   // Pointer to the data.
  16. '    SAFEARRAYBOUND rgsabound[1]; // One bound for each dimension.
  17. '} SAFEARRAY;
  18. 'SAFEARRAYBOUND is a two-longword structure, the first 32 bits hold the # of
  19. 'elements in the array, the second 32 bits hold the lower bound of the array.
  20. 'There is one structure for every dimension of the array.
  21. 'http://groups-beta.google.com/group/microsoft.public.vc.vcce/browse_thread/thread/7f2bfbdb6ef17e98/a90475b71136f83b?q=OleSafeArray+visual+basic&rnum=2&hl=en#a90475b71136f83b
  22.  
  23. 'Public Type OLEVARIANT
  24. '    vt As Integer 'variable type
  25. '    wReserved1 As Integer
  26. '    wReserved2 As Integer
  27. '    wReserved3 As Integer
  28. '    lVal As Integer
  29. '    iVal As Integer
  30. '    bstrVal As Long
  31. '    pUnkVal As Long
  32. '    pArray As Long
  33. '    pvRecord As Long
  34. '    pRecInfo As Long
  35. 'End Type
  36.  
  37.     Dim pArray As Long
  38.     Dim ppArray As Long
  39.     Dim ppVarStruct As Long
  40.    
  41.     Dim intDims As Integer
  42.     Dim intFeatures As Integer
  43.     Dim lElements As Long
  44.     Dim lLocks As Long
  45.     Dim lDataPtr As Long
  46.     Dim lElementCount As Long
  47.     Dim lLbound As Long
  48.    
  49.     Dim lOffset As Long
  50.     Dim lDataTemp As Long
  51.     Dim i As Long
  52.     Dim vType As Long
  53.     '----------------------------------------------------------------
  54.     ' First get a pointer to the variant.
  55.     ppVarStruct = VarPtr(varArray)
  56.    
  57.     'Get the variable type
  58.     'CopyMemory vType, ByVal ppVarStruct, 2
  59.     'Debug.Print "vType: " & vType
  60.  
  61.     ' Get the pointer to the data *inside* the variant.  The VARTYPE is 2 bytes,
  62.     ' and each of the three reserved words are also 2 bytes, giving 8 bytes total.
  63.     '
  64.     CopyMemory ppArray, ByVal ppVarStruct + 8, 4
  65.    
  66.     ' Now parse the SafeArray structure.  The most important parts to me are the
  67.     ' Number of elements and the pointer to the actual data.
  68.     '
  69.     lOffset = 0
  70.     CopyMemory intDims, ByVal (ppArray + lOffset), ByVal Len(intDims)
  71.  
  72.     lOffset = lOffset + Len(intDims)
  73.     CopyMemory intFeatures, ByVal (ppArray + lOffset), ByVal Len(intFeatures)
  74.  
  75.     lOffset = lOffset + Len(intFeatures)
  76.     CopyMemory lElements, ByVal (ppArray + lOffset), ByVal Len(lElements)
  77.  
  78.     lOffset = lOffset + Len(lElements)
  79.     CopyMemory lLocks, ByVal (ppArray + lOffset), ByVal Len(lLocks)
  80.  
  81.     lOffset = lOffset + Len(lLocks)
  82.     CopyMemory lDataPtr, ByVal (ppArray + lOffset), ByVal Len(lDataPtr)
  83.  
  84.     lOffset = lOffset + Len(lDataPtr)
  85.     CopyMemory lElementCount, ByVal (ppArray + lOffset), ByVal Len(lElementCount)
  86.  
  87.     lOffset = lOffset + Len(lElementCount)
  88.     CopyMemory lLbound, ByVal (ppArray + lOffset), ByVal Len(lLbound)
  89.     '===============================================
  90.     Dim strElement As String
  91.    
  92.     If lElementCount > 0 Then
  93.         ReDim Elements(lElementCount)
  94.         For i = 0 To (lElementCount - 1)
  95.                 'Copy the array string element pointer to lDataTemp
  96.                 CopyMemory lDataTemp, ByVal lDataPtr, ByVal lElements
  97.                
  98.                 'strElement = Space(100)
  99.                
  100. '************************************************
  101. '************************************************
  102. '************************************************
  103. 'Here is my problem, if I comment these lines, everything works fine always, If not, after few function calls I get can not write or read memory errors and the program exits. I guess I am not copying the safearray string variables correctly from the Variantto the returned array, please help here.
  104.  
  105.                 'Copy the array string element to the variable strElement
  106.                 CopyMemory strElement, lDataTemp, ByVal lElements
  107.  
  108.                 Elements(i) = StrConv(strElement, vbFromUnicode)
  109.  
  110.                 'CopyMemory Elements(i), lDataTemp, ByVal lElements
  111. '************************************************
  112. '************************************************
  113. '************************************************                
  114.  
  115.                 'Next array element pointer
  116.                 lDataPtr = lDataPtr + lElements
  117.                 strElement = ""
  118.         Next i
  119.     End If
  120.    
  121.     'I tried to free the safearray, it works
  122.     'Debug.Print "SafeArrayDestroyData: " & SafeArrayDestroyData(ppArray)
  123.     'Debug.Print "SafeArrayDestroy: " & SafeArrayDestroy(ppArray)
  124. End Sub

Thank you