How to return String-Arrays from C++ COM component to C#?

Want to return an array of strings from native COM component to managed code?

You need to declare the string array as SAFEARRAY(VARIANT) in the COM code.

IDL for the function that returns the array of strings for the COM component would look like,

      [id(1)] HRESULT GetStringArray([out] SAFEARRAY(VARIANT)* StrArray);

The C++ implementation of the function should create a Safe Array of variants and initialize each variant with a BSTR as shown below:

STDMETHODIMP CNativeCOMComponent::GetStringArray(SAFEARRAY** pStrArray)
   SAFEARRAYBOUND bounds[] = {{2, 0}}; //Array Contains 2 Elements starting from Index '0'

   SAFEARRAY* pSA = SafeArrayCreate(VT_VARIANT,1,bounds); //Create a one-dimensional SafeArray of variants

   long lIndex[1];

   VARIANT var;

   lIndex[0] = 0; // index of the element being inserted in the array

   var.vt = VT_BSTR; // type of the element being inserted

   var.bstrVal = ::SysAllocStringLen( L"The First String", 16 ); // the value of the element being inserted

   HRESULT hr= SafeArrayPutElement(pSA, lIndex, &var); // insert the element

   // repeat the insertion for one more element (at index 1)

   lIndex[0] = 1;

   var.vt = VT_BSTR;

   var.bstrVal = ::SysAllocStringLen( L"The Second String", 17 );

   hr = SafeArrayPutElement(pSA, lIndex, &var);

   *pStrArray = pSA;

   return S_OK;

In the above sample we are inserting two BSTR variants into the created Safe Array. Once the Array is filled with the variants (of type VT_BSTR), it can be retrieved from the C# managed code as shown below:

   CNativeCOMComponent ComObj = new CNativeCOMComponent();

   Array arr;

   ComObj.GetStringArray(out arr); //arr would now hold the two strings we have sent from the COM code