Search code examples
c++arraysstringcomidl

How to pass an array of strings through a COM (C++) API


We have a COM API for our application (which is written in VC++) which exposes a few functionalities so that the users can automate their tasks. Now, I'm required to add a new method in that, which should return a list/array/vector of strings. Since I'm new to COM, I was looking at the existing methods in the .idl file for that interface.

One of the existing methods in that idl file looks like this:

interface ITestApp : IDispatch
{
    //other methods ..
    //...
    //...
    //...
    [id(110), helpstring("method GetFileName")] HRESULT GetFileName([out, retval] BSTR *pFileName);
    //...
    //...
    //...
};

My task is to write a similar new method, but instead of returning one BSTR string, it should return a list/array/vector of them.

How can I do that?

Thanks!


Solution

  • Since yours is an automation-compatible interface, you need to use safearrays. Would go something like this:

    // IDL definition
    [id(42)]
    HRESULT GetNames([out, retval] SAFEARRAY(BSTR)* names);
    
    // C++ implementation
    STDMETHODIMP MyCOMObject::GetNames(SAFEARRAY** names) {
      if (!names) return E_POINTER;
      SAFEARRAY* psa = SafeArrayCreateVector(VT_BSTR, 0, 2);
    
      BSTR* content = NULL;
      SafeArrayAccessData(psa, (void**)&content);
      content[0] = SysAllocString(L"hello");
      content[1] = SysAllocString(L"world");
      SafeArrayUnaccessData(psa);
    
      *names = psa;
      return S_OK;
    }
    

    Error handling is left as an exercise for the reader.