I was working on an app that uses CCW to access a managed library. One of the methods in the library returns an array<String^>^. The COM version of this method will have a SAFEARRAY** as the [out,retval] parameter. Not having a lot of COM experience, I was pretty surprised to find how little documentation there is on MSDN or any where else for that matter on using a SAFEARRAY. All I wanted to do was to enumerate the returned array. Eventually it turned out to be pretty easy. For the interested few, here’s what you need to do.
SAFEARRAY* pSA= NULL;
if(SUCCEEDED(pXXXX->GetXXXX(XXXXid, &pSA)))
{
long lbound = 0, ubound = 0;
SafeArrayGetLBound (pSA, 1, &lbound);
SafeArrayGetUBound (pSA, 1, &ubound);
BSTR* s = NULL;
SafeArrayAccessData(pSA, (void**) &s);
wcout << "XXXXXXXXXXXX" << endl;
for(long i=lbound; i<=ubound; i++)
{
wcout << "\t" << s[i] << endl;
}
SafeArrayUnaccessData(pSA);
SafeArrayDestroy (pSA);
}
Hi Nish,
Safe arrays can be pretty daunting when you first use them but they’re incredibly useful for interop with managed code. I would however suggest that you use ATL’s CComSafeArray template class which provides a more type safe and elegant solution. It also takes care of destroying the safe array deterministically which you forgot to do in your sample (you need to call SafeArrayDestroy to destroy the array as well as the resources contained within the array). CComSafeArray is declared in atlsafe.h.
Cheers,
Kenny
Thanks Kenny,
I’ll look into CComSafeArray – I think it would be far smoother to use than a SAFEARRAY.
Oh, and Kenny, I’ve added the call to SafeArrayDestroy 🙂