1

I created a C++ DLL which take an empty array as VARIANT. I will run some sql query inside DLL and store output in empty array. When I tried this, excel crashes.

My VBA call :

Dim outArray(17) As Variant
bo = GetData_V(dbFilePath, id, inArray, outArray, counter)

and function is defined as

Declare Function GetData_V& Lib "xyz.dll" (ByVal path As String, ByRef inputArr() As String, ByRef output As Variant, ByRef id As Integer)

C++ Implementation :

        CComSafeArray<VARIANT> out_sa(nCount);
        HRESULT hr;
        for (LONG i = lowerBound; i <= upperBound; i++)
        {
            CComVariant variant = CComVariant(outputCustom[i]);
            hr = out_sa.SetAt(i,variant);
            if (FAILED(hr))
            {
                return false;
            }
        }
        CComVariant(out_sa).Detach(outputArray);

Where outputCustom is defined as

outputCustom = new char*[nCount+1];

and has string values.

When I try to run it, Excel crashes. I don't know how to return outputArray back to VBA.

7
  • your function definition does not show a return variable type Commented Nov 27, 2017 at 5:54
  • have you successfully written a dll that accepts a single integer and returns a single integer? Commented Nov 27, 2017 at 5:56
  • @jsotola when I tried to add a return type, it shows 'expected end of statement.' . I tried putting a fullstop but still giving error. Also I haven't tried returning a integer. Commented Nov 27, 2017 at 6:01
  • You have declared your function to return a Long (i.e. the & on the end of GetData_V&) - are you doing so? Also, your declaration is defining the parameters to be ByVal path As String, ByVal path As String, ByRef inputArr() As String, ByRef output As Variant, ByRef id As Integer (with path repeated?) but your call (i.e. dbFilePath, id, inArray, outArray, counter) doesn't seem to match that. Commented Nov 27, 2017 at 6:29
  • 2
    you have to be able to create and use a simplest possible dll before doing anything more complex. that way you have very minimal debugging in order to make it work. ... once it works, add more calling arguments... then finally add the return parameter Commented Nov 27, 2017 at 6:37

1 Answer 1

1

So this is how I return String array from C++ DLL to VBA: I changed my VBA function declaration to this :

Declare Function GetData_V Lib "xyz.dll" (ByVal path As String, ByVal id As String, ByRef inputArr() As String, ByRef output() As String) As Variant()

C++ implementation : Changed return type of C++ function to SAFEARRAY* and modified the code as follow:

   SafeArrayLock(*outputArray); 
    for (LONG i = 0; i < countElements; i++)
    {
        CComBSTR bstr = CComBSTR(outputCustom[i]);
        SafeArrayPutElement(*outputArray, &i, bstr);
    }
    SafeArrayUnlock(*outputArray); 

    delete [] outputCustom;

    return *outputArray;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.