Search code examples
c++comactivexvariantidispatch

how to convert com instance to variant, to pass it in idispach invoke


i want to pass a com object instance as a variant parameter to another active x object function, for that i need to convert the idispatch pointer to a variant? i am not sure.

hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    if (FAILED(hr))
    { 
        return;
    }
    hr = CLSIDFromProgID(objectName.c_str(), &clsid);
    if (FAILED(hr))
    {
        return;
    }
    hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pApp));
    if (FAILED(hr) || pApp == nullptr) {
        return;
    }

this is the instance creating code, after that i am using this :

VARIANT v;
    VariantInit(&v);
    v.pdispVal = pApp;
    v.ppdispVal = &pApp;
    v.vt = VT_DISPATCH;
    return v;

and passing it to an active x method, but it is giving access violation after invoke. what i am doing wrong?


Solution

  • If you want to use the VARIANT raw structure, you can code it like this:

    VARIANT v;
    VariantInit(&v);
    pApp->AddRef();
    v.pdispVal = pApp;
    v.vt = VT_DISPATCH;
    ...
    // later on, some code (this code or another code) will/should call this
    VariantClear(&v); // implicitely calls pdispVal->Release();
    

    Or, if you're using the Visual Studio development environment, then you can just use the _variant_t or CComVariant (ATL) smart wrappers which I recommend. In this case, you can just call it like this:

    IDispatch *pApp = ...
    
    // both wrappers will call appropriate methods
    // and will release what must be, when destroyed
    CComVariant cv = pApp;
    
    // or
    
    _variant_t vt = pApp;
    

    PS: don't use both wrapper classes, make your choice. If a project uses ATL, I uses CComVariant, otherwise _variant_t, for example.