0

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!

Piyush Soni
  • 1,356
  • 3
  • 17
  • 40
  • Sorry, my copy of Inside Distributed COM only shows example for raw strings or `int` arrays and it has been way too long to remember how to do this. – crashmstr Jul 31 '14 at 18:38
  • P.S. : I'm not sure which part of the question is not clear. Rather than voting to close it, could the users please ask? If you think the question is 'too broad' or can have many answers, you can help with at least one or two of those. Thanks! – Piyush Soni Jul 31 '14 at 18:44
  • I did not vote to close nor did I downvote. It is clear to me what you need, but I've forgotten how to do it. – crashmstr Jul 31 '14 at 18:51
  • @crashmstr, I apologize for the confusion, my comment was for the other votes (3 of them) who voted to close it and not for you. Appreciate your comment. – Piyush Soni Jul 31 '14 at 23:37

1 Answers1

4

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.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85