SAFEARRAYs can contain elements of any allowable type, including BSTRs and user-defined data structures. BSTRs inside arrays should be manipulated with the same OLE Automation functions as ordinary BSTRs. Always remember to free any existing BSTR before allocating a new one, or use the reallocation function. Do not directly modify BSTR data.
The following example creates or redimensions an array of strings. Any existing BSTR data in the array is freed before new data is copied into the array.
short WINAPI StringArray(LPSAFEARRAY *ppsa)
{
unsigned long l;
BSTR bstr;
LPSAFEARRAY psa;
SAFEARRAYBOUND sa;
HRESULT hr;
sa.lLbound = 0;
sa.cElements = 3;
if (*ppsa == NULL) // array not yet initialized
{
if ((psa = SafeArrayCreate(VT_BSTR, 1, &sa)) == NULL)
return -2;
*ppsa = psa;
}
else
{
if ((*ppsa)->cDims != 1) // check array dimensions
return -1;
}
// loop through the array; get each element and free
// any existing string, then allocate the new string
// and put it in the array
for (l = sa.lLbound; l < sa.cElements; l++)
{
if (FAILED(SafeArrayGetElement(*ppsa, &l, &bstr)))
return -4;
SysFreeString(bstr);
if ((bstr = SysAllocString((BSTR)"test string")) == NULL)
return -5;
if (FAILED(SafeArrayPutElement(*ppsa, &l, bstr)))
return -6;
}
return 0;
}
Declared and called from Visual Basic:
Declare Function StringArray Lib "debug\ADVDLL.DLL" _
(s() As String) As Integer
Sub StringArrayTest()
Dim s() As String
Dim t(1) As String
t(1) = "Original String"
MsgBox StringArray(s) & ":" & UBound(s) & ":" & s(1)
MsgBox StringArray(t) & ":" & UBound(t) & ":" & t(1)
End Sub