Using Arrays of Strings

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