Results 1 to 5 of 5

Thread: converting VARIANT to ...

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Mar 2002
    Location
    UK
    Posts
    18

    Arrow converting VARIANT to ...

    I need to know how to get a VARIANT data type into something more useful like a char array or a CString. I have tried the following.

    void CTestmodulesDlg::OnCheckResponseOK(VARIANT FAR* Response)
    {
    COleVariant MyVar;
    char mc [10];
    CString MyCStr;

    MyVar.Attach (*Response);

    mc [0] = *MyVar.pbVal;
    mc [1] = *(MyVar.pbVal+1);
    mc [2] = *(MyVar.pbVal+2);
    mc [3] = *(MyVar.pbVal+3);
    mc [4] = *(MyVar.pbVal+4);
    mc [5] = 0;

    MyCStr = MyVar.pbVal;
    }

    But looking at the mc array and the CString it seems that each element has a terminating 0 after it. For example if Response is "Hello" then it is stored as 'H',0,'e',0,'l',0,'l',0,'o',0.

    Any suggestions?

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    No, that's correct.

    OLE strings are Unicode, i.e. 16-bit. So, you end up with extra nulls embedded in the string - which is then terminated with a double null (i.e. a SINGLE null wchar_t character).

    I think OLE strings have a length as well, so the terminator may not be there, I think I recall something in the MS docs saying not to rely on it.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    To get the string out of a VARIANT, do this:
    CString str;
    str = (LPWSTR)Response->bstrVal;


    Be aware that if the bstr does not contain a terminating 0, this method won't work. I#ll post a better method later.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Mar 2002
    Location
    UK
    Posts
    18
    Thanks for the tips. I how figured out how to do it:


    void CTestmodulesDlg::OnCheckResponseOK(const VARIANT FAR& Response)
    {
    _variant_t MyVar (Response);
    CString RespStr;

    RespStr = MyVar.bstrVal;
    ////////////// or
    CString RespStr (Response);
    /////////////
    }

    No need for the cast.It's always easy when you know how.

  5. #5
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    As Jeff Prosise describes it, a BSTR is a counted UNICODE string. The character count is a WORD just before the first character. BSTR is a typedef of (unsigned int*), which points to the first character. This is why you can simply cast it to WCHAR*.
    This would be the memory image of the string "Hello" (hex):
    Code:
    05 00 48 00 65 00 6c 00 6c 00 6f 00 00 00
    count  'H'   'e'   'l'   'l'   'o'   '\0'
           ^
    value of the BSTR var points here
    Therefore, you can do
    Code:
    void BSTRtoCString(BSTR bstrIn, CString &strOut)
    {
      WORD wCount = *(((WORD*)bstrIn) - 1);
      WCHAR *ws = new WCHAR[wCount + 1];
      memcpy(ws, bstrIn, wCount * sizeof(WCHAR));
      ws[wCount] = 0;
      strOut = ws;
      delete ws;
    }
    This should work, but I can't guarantee it.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

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