Search code examples
c++arraysdynamiccomborland-c++

How to call a method that returns an array of strings in Borland C++?


I've created a COM wrapper in C# with a method that returns an array of strings:

public string[] GetArrayOfStrings()
{
    string[] array = new string[3];
    array[0] = "first";
    array[1] = "second";
    array[2] = "third";

    return array;
}

In VB6 I'm calling that method and presenting strings in a list like this:

Dim s() As String
s = obj.GetArrayOfStrings()
For i = LBound(s) To UBound(s)
    List1.AddItem s(i)
Next i

Does anyone know how to call that method from Borland C++ and get all elements in the returning array?


Solution

  • Arrays in COM are handled by the SAFEARRAY struct.

    Depending on how the COM object exposes the array, it may return a SAFEARRAY directly, eg:

    SAFEARRAY *psa = obj->GetArrayOfStrings();
    VARTYPE vtype;
    SafeArrayGetVartype(psa, &vtype);
    if (vtype == VT_BSTR)
    {
        LONG lBound, uBound;
        SafeArrayGetLBound(psa, 0, &lBound);
        SafeArrayGetUBound(psa, 0, &uBound);
        for(LONG i = lBound; i <= uBound; ++i)
        {
            BSTR str;
            SafeArrayGetElement(psa, &i, &str);
            ...
            SysFreeString(str);
        }
    }
    SafeArrayDestroy(psa);
    

    Or it may be wrapped inside of a VARIANT struct instead, eg:

    VARIANT v = obj->GetArrayOfStrings();
    if (V_VT(&v) & VT_ARRAY)
    {
        SAFEARRAY *psa = V_ARRAY(&v);
        ...
    }
    VariantClear(&v);
    

    Either way, the elements inside of the array may or may not be wrapped inside of VARIANT structs, eg:

    SafeArrayGetVartype(psa, &vtype);
    if (vtype == VT_VARIANT)
    {
        ...
        VARIANT elem;
        VariantInit(&elem);
        SafeArrayGetElement(psa, &i, &elem);
        ...
        VariantClear(&elem);
        ...
    }