If IB inherits from IA, and you want to use the IA interface on IB don’t just
cast IB to IA. Although the cast will often work, it will fail if proxy or stub
code is involved. Instead, you should use QueryInterface to obtain a pointer to
IA, e.g.:
Note: QueryInterface cannot be used to obtain an unrelated interface – you have
to use CoCreateInstance again.
Tear-off Interfaces: Interfaces that defer initialisation until the last minute
– typically to conserve limited resources (such as database connections)
One of the key things provided by IDL to COM is the marshalling information
[in, size_is(iSize)] SHORT* piArray,
[out]
LONG* lpResult);
The difference between size_is and max_is is simply the difference between
defining the size of an array by the number of elements it contains (size_is) or
its highest index (max_is). Therefore size_is(X) is always the same as
max_is(X-1).
We’d then call the code something like this:
SHORT piData [5];
for (int i = 0; i<5; i++) piData[i] = i*i;
hr = I->ArraySum(5, piData, &result);
std::cout << result << std::endl;
[out, iid_is(riid)] IUnknown ** ppvObject);
To implement properties, we have to implement accessors (get) and/or mutators (set). Like methods, properties can be added through a wizard. Since internally properties are implemented as a get function and a set function, IDL needs to be specified for each function specified. Just to be difficult, because these are functions, we can add parameters to our properties if we wish!
Having added a property through the wizard, it’s easy to flesh out the generated methods get_PropertyName and put_PropertyName as these are exactly the same as any other “STDMETHODIMP” function.
However, referring to a property through C++ is not so straightforward. The
wizard will have added an IDispatch and handler to the code for us so (after a
bit of messing around) I was able to do this:
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
I->Invoke(5, IID_IFirst_ATL, NULL, DISPATCH_PROPERTYGET,
&dispparamsNoArgs, &var, NULL, NULL);
std::cout << var.lVal << std::endl;
[propput, id(5), helpstring("property DaveTest")]
HRESULT DaveTest([in] LONG
newVal);
hr = CoCreateInstance(CLSID_First_ATL, NULL,
CLSCTX_INPROC_SERVER, IID_IFirst_ATL, (void**) &I);
hr = IPtr.CoCreateInstance(CLSID_First_ATL, NULL,
CLSCTX_INPROC_SERVER);
pINewBase(pIExistingChildInterface);
IQIPtr->AddNumbers(10,20, &result);
IPtr.p->QueryInterface(IID_IFirst_ATL, (void**) &pI2);
pI2->AddNumbers(10,20, &result);