dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: VARIANTS inside a SAFEARRAY

  1. #1
    Join Date
    Aug 2004
    Posts
    133

    VARIANTS inside a SAFEARRAY

    I have some data that I want to put inside VARIANTS inside a Safearray.

    Im having trouble putting the data inside the SAFEARRAY.

    WHen I cast a pointer to a VARIANT,

    VARIANT* pvDataIn = reinterpret_cast<VARIANT*>(pSafeData->pvData);

    1). Can I just use pointer arithmatic to add SafeArrayPutElement().

    2). do I need to first put the data into VARIANTs then put them into the safearray or becuase its an safearray of vairants can I just add them straight into the array, and if so do I need to call VariantInit()...

    Thanks for any help..

  2. #2
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: VARIANTS inside a SAFEARRAY

    When dealing with VARIANTs, use the Smart Wrapper Class CComVariant.

    When dealing with SAFEARRAYs, use the Smart Wrapper Class CComSafeArray.

    Now, putting these two together, you will create a VARIANT of SAFEARRAYs like this -
    Code:
    CComSafeArray <BSTR> saBstrArray;
    
    // Insert BSTRs into the array: saBstrArray
    
    // Insert the SafeArray into the Variant
     CComVariant varArrayWrapper (saBstrArray);
    
    // Converting to pure variant -
    VARIANT *pVal = NULL;
    varArrayWrapper.Detach (pVal);
    Attached is a sample Solution that comprises of -

    • A COM Server - CreateSafeArrays.Dll that provides a SAFEARRAY of Strings to the client
    • A Console Application Client called - UseSafeArrays.exe that fetches the SAFEARRAY from the COM DLL and displays them on the screen.
    This attached sample will show you how to -
    • Create of a Safe Array.
    • Assign it to a Variant.
    • Interpret the Safe Array on the Client
    Attached Files Attached Files
    Last edited by Siddhartha; October 11th, 2005 at 04:49 PM. Reason: Formatting...

  3. #3
    Join Date
    Aug 2004
    Posts
    133

    Re: VARIANTS inside a SAFEARRAY

    Thanks for the quick response. I cant seem to get the example working becuase I use vc6 and atlsafe.h is vc7

  4. #4
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: VARIANTS inside a SAFEARRAY

    Quote Originally Posted by polus
    I cant seem to get the example working becuase I use vc6 and atlsafe.h is vc7
    Not using VS 7.0 is indeed a tragic constraint...

    Okay, here is how you would pass a Safe Array as a VARIANT - and this is VC 6.0 Compliant:
    Code:
    // The VARIANT returned contains a Safe Array
    STDMETHODIMP CArrayMaker::get_StringArray(VARIANT *pVal)
    {
      // The Safe Array pointer
      SAFEARRAY *pStringArray = NULL;
      SAFEARRAYBOUND rgsabound[1];
    
      // Create it - Assume a sample Safe Array of BSTRs
      pStringArray = SafeArrayCreate (VT_BSTR, 1, rgsabound);
    
      // Populate the Safe Array... with BSTRs
    
      // Use the CComVariant wrapper class - Good Practice!
      CComVariant varOut;
    
      // Tell the VARIANT that it contains an Array
      varOut.vt = VT_ARRAY;
    
      // Assign the Array
      varOut.parray = pStringArray;
    
      // Detach the wrapped Variant Object to the output paramater
      return varOut.Detach (pVal);
    }
    ...The client side code doesn't change much other than the fact that instead of using CComSafeArray wrapper, you would directly use the pVariantIn->parray parameter as a pointer to the received Safe Array.
    Last edited by Siddhartha; September 9th, 2005 at 04:08 AM.

  5. #5
    Join Date
    Aug 2004
    Posts
    133

    Re: VARIANTS inside a SAFEARRAY

    Not using VS 7.0 is indeed a tragic constraint...
    Yeah... Not upto me unfortuantly....

    Thanks alot for the help. Not meaning to be annoying but... I need a Safearray of Variants.

    Basically I need to store a two dimesional safearray to store many (1st Dim->) elements containing (2nd Dim->) 13 ints and floats:

    Code:
    VARIANT vrDataIn[13];
    SAFEARRAY *pSafeData;
    SAFEARRAYBOUND rgsabound[2];
    
    for ( int nI=0; nI<13; nI++ )
    {
    VariantInit( &vrDataIn[nI] );
    }
    
    rgsabound[0].lLbound = 0;
    rgsabound[0].cElements = 2;
    
    rgsabound[1].lLbound = 0;
    rgsabound[1].cElements = 13;
    
    pSafeData = SafeArrayCreate( VT_VARIANT, 2, rgsabound );
    _ASSERTE( pSafeData != NULL );
    
    // Check bounds.....etc... then fill array
    
    LONG lIndices[2] = { 0, 0 };
    
    for ( 0 to 1 )
    {
          for (0 to 12)
       {
    
            vrDataIn[0].vt = VT_UINT;
            vrDataIn[0].uintVal = nType[nElements];
            SafeArrayPutElement( pSafeData, lIndices, &vrData[0]);
    			_ASSERTE( SUCCEEDED(hr) );
    			lIndices[1]++;
    
       }
    lIndices[0]++;
    
    }
    Obviously the for loops arnt proper C++, I just want to demostrate what Im trying to accomplish (and I know the code is pretty bad :-/ )

  6. #6
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: VARIANTS inside a SAFEARRAY

    It is absolutely OK to have a Safe Array of VARIANTs.

    In this case, you would create a SafeArray, populate it with VARIANTs, and then, wrap this SafeArray into another VARIANT and transact that one.

    To make things clear, this is a VARIANT version of my sample above -
    Code:
    // The VARIANT returned contains a Safe Array
    STDMETHODIMP CArrayMaker::get_StringArray(VARIANT *pVal)
    {
      CComVariant varTest;
    
      // The Safe Array pointer
      SAFEARRAY *pVariantsArray = NULL;
      SAFEARRAYBOUND rgsabound[1];
    
      // Create it: A Safe Array of VARIANTs
      pVariantsArray = SafeArrayCreate (VT_VARIANT, 1, rgsabound);
    
      // Populate the Safe Array... With VARIANTs
    
      // Use the CComVariant wrapper class - Good Practice!
      CComVariant varOut;
    
      // Tell the VARIANT that it contains an Array
      varOut.vt = VT_ARRAY;
    
      // Assign the Array
      varOut.parray = pVariantsArray;
    
      // Detach the wrapped Variant Object to the output paramater
      return varOut.Detach (pVal);
    }
    ...Now, on the client side pVariantIn->parray will point to a SafeArray of Variants...

    BTW, you can do away with this -
    Quote Originally Posted by polus
    Code:
    for ( int nI=0; nI<13; nI++ )
    {
    	VariantInit( &vrDataIn[nI] );
    }
    ...Initialization of VARIANTs if you use CComVariant. This is VC 6.0 compliant, and I strongly recommend it...
    Code:
     // The constructor of the wrapper CComVariant will
      // Do this trivial stuff for you!
      CComVariant() throw()
      {
    	::VariantInit(this);
      }
    Last edited by Siddhartha; September 9th, 2005 at 04:56 AM. Reason: "this case" and not "any case"...

  7. #7
    Join Date
    Aug 2004
    Posts
    133

    Re: VARIANTS inside a SAFEARRAY

    Ok thats great.

    Just out of interest, why do wrap the Safearray in a Variant?

    Also; when I create a safearray with 2 dimensions it never seems to have the two dimmensions when I look at pvData in memory, nor does it seem to have the second dimensionm listed, there so many things going wrong its beginning to get irritating which is hampering my ability to understand it all...
    Last edited by polus; September 9th, 2005 at 04:48 AM.

  8. #8
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: VARIANTS inside a SAFEARRAY

    Quote Originally Posted by polus
    why do wrap the Safearray in a Variant?
    Because, a VARIANT (by default) is transactable across COM Boundaries. SAFEARRAY is not.

  9. #9
    Join Date
    Aug 2004
    Posts
    133

    Re: VARIANTS inside a SAFEARRAY

    OK Ill do it that way thanks...

  10. #10
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: VARIANTS inside a SAFEARRAY

    Quote Originally Posted by polus
    OK Ill do it that way thanks...
    Great... You are welcome...

Posting Permissions

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


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)