The following code worked just fine thank you with one COM client, but with a new client (the updated version of the same software) string_array_to_bstr_safearray_variant
throws an access violation and everything dies.
Can anyone tell me if I'm doing something wrong that I was getting away with before..? Am I failing to allocate memory properly?
#include "comutil.h"
void string_array_to_bstr_safearray_variant(long arraylength,char ** in_array,VARIANT *out_variant)
{
CComSafeArray<BSTR> out_array;
ATLENSURE_SUCCEEDED(out_array.Create(arraylength));
for (int i=0;i<arraylength;i++)
ATLENSURE_SUCCEEDED(out_array.SetAt(i,_com_util::ConvertStringToBSTR(in_array[i])));
CComVariant ccv(out_array);
HRESULT hr = ccv.Detach(out_variant);
ATLENSURE_SUCCEEDED(hr);
}
//names: output parameter to contain variant holding safearray of bstrs
STDMETHODIMP CCalculation::get_output_shortnames(VARIANT* names)
{
char** names_array = calc_get_short_output_names(calc); //this works fine
string_array_to_bstr_safearray_variant(output_length,names_array,names); //this fails before returning
return S_OK;
}
Edit: Debugger info
Without a debugger, I get an access violation.
Stepping through this code with the debugger it appears to work. output_length
is set correctly; out_array
is created and filled correctly and so is out_variant
as far as I can tell through variable watching. However, the COM client still fails, saying "lisp value has no coercion to VARIANT with this type: #<safearray...>"
(which is odd because a previous version of the client interprets the return value just fine). It then crashes complaining that it's out of memory.
Running the code inside the debugger, but letting it run rather than stepping, it failed inside the constructor of CComVariant
, complaining of an invalid argument thrown because the inner call to SafeArrayCopy
failed.
Edit: on another recent step-through it failed in the loop, so maybe the problem is with CComSafeArray as @terriblememory suggests?