Click to See Complete Forum and Search --> : How do I pass an array of BSTRs in COM?


April 21st, 1999, 09:38 AM
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, (henrik.johansson@meditelligence.se)

April 27th, 1999, 01:22 PM
Use SAFEARRAY inside a VARIANT

May 5th, 1999, 10:55 PM
//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::put_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

ksheeraj
May 6th, 1999, 02:50 AM
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