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

    How do I pass an array of BSTRs in COM?

    Hi!

    I need to pass an array of strings from a COM object to a client. I have tried with the CComArray class I found on this site, but I didn't get it to work.
    Here's what I did:


    <COM object>
    <idl>
    [id(1), helpstring("method Testing")] HRESULT Testing([out] VARIANT* p_pVar);
    <source>
    STDMETHODIMP CBOGraph::Testing(VARIANT* p_pVar)
    {
    CComArray<BSTR> array;
    if (!array.Initialize(p_pVar, 1, false))
    return E_FAIL;

    BSTR bstrTmp;
    bstrTmp = ::SysAllocString(OLESTR("teststring"));
    array.SetAt(0, bstrTmp);

    return S_OK;
    }

    <CLIENT>
    void TestTesting()
    {
    VARIANT var;
    m_pBOGraph->Testing(&var);
    CComArray<BSTR> array;
    if (array.Attach(&var, true))
    {
    BSTR d;
    bool bContinue = true;
    int nSize = array.Size();
    for (int i = 0; bContinue && i < nSize; i++)
    {
    bContinue = array.GetAt(i, d);
    if (bContinue)
    {
    CString sTmp = OLE2T(d);
    TRACE(_T("TestTesting(): sTmp = %s"), sTmp);
    }
    }
    }
    }




    What do I do wrong?
    Or is there a better way to pass an array of strings in COM?

    Thanks,
    /Henrik Johansson, ([email protected])


  2. #2
    Guest

    Re: How do I pass an array of BSTRs in COM?

    Use SAFEARRAY inside a VARIANT


  3. #3
    Guest

    Re: How do I pass an array of BSTRs in COM?

    //This is a chunk of code from Biginning ATL Com programming From WROX
    //It is a good book and I recommend it for beginners.
    //I hope this helps

    //The vector is declared in the header file as a vector that can hold CComBSTR objects.
    std::vector<CComBSTR> m_vecColors;



    //The following is in the cpp file
    //Now load the vector with strings
    HRESULT CColorObject::FinalConstruct()
    {
    m_vecColors.push_back(CComBSTR(L"Red"));
    m_vecColors.push_back(CComBSTR(L"Orange"));
    m_vecColors.push_back(CComBSTR(L"Yellow"));
    m_vecColors.push_back(CComBSTR(L"Green"));
    m_vecColors.push_back(CComBSTR(L"Blue"));
    m_vecColors.push_back(CComBSTR(L"Indigo"));
    m_vecColors.push_back(CComBSTR(L"Violet"));


    //call this function from your client when you need to get the array of strings
    STDMETHODIMP CColorObject::get_Colors(VARIANT *pVal)
    {
    // TODO: Add your implementation code here
    VariantInit(pVal);
    pVal->vt = VT_ARRAY | VT_BSTR;
    SAFEARRAY* psa;
    SAFEARRAYBOUND bounds = {m_vecColors.size(), 0};
    psa = SafeArrayCreate(VT_BSTR, 1, &bounds);

    BSTR* bstrArray;

    SafeArrayAccessData(psa, (void**)&bstrArray);
    std::vector<CComBSTR>::iterator it;
    int i = 0;

    for (it = m_vecColors.begin(); it != m_vecColors.end(); it++, i++)
    {
    bstrArray[i] = SysAllocString((*it).m_str);
    }

    SafeArrayUnaccessData(psa);
    pVal->parray = psa;


    ATLTRACE(_T("Returning SafeArray which has these members:\n"));
    DumpVector();

    return S_OK;
    }


    //call this function from your client when you need to send an array of strings
    //to the com object

    STDMETHODIMP CColorObject:ut_Colors(VARIANT newVal)
    {
    // TODO: Add your implementation code here
    if((newVal.vt & VT_ARRAY) == 0)
    return E_INVALIDARG; //Not an array

    if((newVal.vt & VT_BSTR) == 0)
    return E_INVALIDARG;

    m_vecColors.clear();
    SAFEARRAY* psa = newVal.parray;
    BSTR* bstrArray;
    SafeArrayAccessData(psa, (void**)&bstrArray);

    for(int i =0; i < psa->rgsabound->cElements; i++)
    {
    m_vecColors.push_back(CComBSTR(bstrArray[i]));
    }

    SafeArrayUnaccessData(psa);

    ATLTRACE(_T("Changing SafeArray to have these members:\n"));
    DumpVector();

    return S_OK;
    }

    //VB client code

    Option Explicit

    Private itf As COLORSLib.IColorObject
    'add a color string to the server array
    Private Sub cmdAddItem_Click()
    If txtNewItem.Text = "" Then
    Exit Sub
    End If

    ' Read data into an array
    ReDim ColorArray(lstColors.ListCount) As String
    Dim x As Integer
    For x = 0 To lstColors.ListCount - 1
    ColorArray(x) = lstColors.List(x)
    Next
    ColorArray(lstColors.ListCount) = txtNewItem.Text
    itf.Colors = ColorArray
    cmdShowObj_Click

    End Sub

    'Get array from server
    Private Sub cmdShowObj_Click()
    Dim Size As Long
    Dim ColorArray As Variant
    ColorArray = itf.Colors
    lstColors.Clear
    Size = UBound(ColorArray) - LBound(ColorArray) + 1
    lblMsg.Caption = "There are " & Str$(Size) _
    & " elements in " & TypeName(ColorArray)
    Dim x As Integer
    For x = LBound(ColorArray) To UBound(ColorArray)
    lstColors.AddItem ColorArray(x)
    Next

    End Sub

    Private Sub Form_Load()
    Set itf = New COLORSLib.ColorObject
    End Sub





  4. #4
    Join Date
    May 1999
    Posts
    35

    Re: How do I pass an array of BSTRs in COM?

    you can use safearray to pass any kind of array.Just make a safearray of the strings at the client side.and at the server side do the unwrapping of the safearray.
    hope this will help.
    ksheeraj

    39639,Leslie St.
    Apt #157
    Fremont USA 94538

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

Featured