-1

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?

Alok Saini
  • 321
  • 7
  • 18
  • 2
    Don't use `ppdisVal`. Also, you probably need to call `pApp.AddRef()` when you wrap a `VARIANT` around it. Because a future call to `VariantClear` will end up calling `pdispVal->Release()`. The best with VARIANTs is to use the smart wrappers such as `_variant_t` or `CComVariant` provided by the Visual Studio environment. With these wrappers, you can just use equality operator. – Simon Mourier Mar 16 '19 at 12:47
  • ok, is there any reference for it? i will try to do it myself though – Alok Saini Mar 16 '19 at 12:49
  • it in atl right? i cant use atl – Alok Saini Mar 16 '19 at 13:13
  • 1
    Do you use Visual Studio? If yes, _variant_t needs comdef.h otherwise CComVariant needs atlcom.h – Simon Mourier Mar 16 '19 at 14:11
  • yes! i got it working! btw, using _variant_t and removing ppdisVal usage, also i am not able to call a function from a variant exception thrown in GetIDsOfNames – Alok Saini Mar 16 '19 at 14:15
  • got it all working!! thanks man , add it as an answer, explaining a little bit and i will select it as answer – Alok Saini Mar 16 '19 at 14:17

1 Answers1

1

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.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298