I am trying to return an array which is a portion of a vector to VBA. The vector is just an array of data from a test file stored as an std::string. I would like to pass a Row variable to the DLL and have this return the given data from that line down to that line + 1000. The issue is that the return variant is just showing as VT_EMPTY in VBA. Can anyone help, I am quite new to C++ in general, and haven't got much COM experience.
LONG __stdcall BDH::GetRange(const uint32_t& Row, const uint32_t& Column, VARIANT* pDest)
{
// Validate row
if (!(Row - 1 > 0))
return -1;
// Validate column
if (!(Column - 1 > 0))
return -1;
// Check row isn't biggest than the last index
if (Row - 1 > SourceData.size())
return -1;
// Check column isn't biggest than the last index of the first element
if (Column - 1 > SourceData[0].size())
return -1;
HRESULT hr = CoInitialize(NULL);
// Initialise the return variant and set the vartype to variant array
VariantInit(pDest);
pDest->vt = VT_VARIANT | VT_ARRAY;
// Create safearray and bound object
SAFEARRAYBOUND Bound[2];
Bound[0].lLbound = 1; // Array starting at 1 (VBA style)
// Decide whether the size should be 1000 or the difference between row and size
if ((SourceData.size() - Row) < 1000)
Bound[0].cElements = SourceData.size() - Row;
else
Bound[0].cElements = 1000;
Bound[1].lLbound = 1; // Start at 1
Bound[1].cElements = SourceData[0].size(); // Set the second dimension size
pDest->parray = SafeArrayCreate(VT_VARIANT, 2, Bound); // Create the safearray within the variant
// Iterators and array indices data
uint32_t i, j;
LONG Indices[2];
for (uint32_t i = Row - 1; i < Row - 1 + 1000; i++)
for (uint32_t j = 0; j < SourceData[i].size() - 1; j++)
{
// Set the index
Indices[0] = i;
Indices[1] = j;
// Create the variant
VARIANT Element;
VariantInit(&Element);
Element.vt = VT_BSTR;
// Set the string value (use SysAllocStringByteLen to reduce space - string is ANSI)
Element.bstrVal = SysAllocStringByteLen(SourceData[i][j].c_str(), SourceData[i][j].size());
// Add the element to the safearray
SafeArrayPutElement(pDest->parray, Indices, &Element);
}
return 0;
}
EDIT: Example of wrapper for this function
__declspec(dllexport) void __stdcall ExampleWrapper(LONG x, LONG y, VARIANT* pDest)
{
BDH bdh;
bdh.GetRange((uint32_t)x, (uint32_t)y, pDest);
}