c++com

C++ Get IDispatch Pointer from SafeArray of VT_DISPATCH type


I have a problem to determinate a valid IDispatch pointer from a SAFEARRAY of type VT_DISPATCH.

What is the right approach?

So far, my experiences are, I always get an exception when trying to AddRef the pointer.

    if (vtS == VT_DISPATCH) {
        IDispatch* iDisp = NULL; void* pData = NULL;
        if (idx) {
            ret = SafeArrayPtrOfIndex(SA, idx, &pData);
            if (ret) goto CleanUp;
        }
        iDisp = (IDispatch*)pData;
        iDisp->AddRef();
        pVGet->vt = VT_DISPATCH;
        pVGet->pdispVal = iDisp;
    }

Please give me a working sample for.


Solution

  • When using SafeArrayPtrOfIndex there's an extra level of indirection, so you should change your code like this:

    void* data;
    SafeArrayPtrOfIndex(sa, &idx, &data);
    
    auto disp = *(IDispatch**)data;
    disp->AddRef();
    

    Or just use SafeArrayGetElement (and you're supposed to lock the array when using SafeArrayPtrOfIndex):

    IDispatch* disp;
    SafeArrayGetElement(sa, &idx, &disp);
    disp->AddRef();