Introduction
Let's have a look at the reuse technique "Aggregation" and
how we can implement this in COM.
Definition
In this reuse mechanism, The Outer COM directly exposes the
Inner COM's interfaces to the client. I will try to explain the
steps involved to attain Aggregation relation between the
InnerCom and OuterCom in the simplest way possible, so
that beginners in COM can understand and workout.
Let's work on an example to establish aggregation relation
between the Calculator Component (InnerCom), which already is available with us
and ComplexCalculator, which we are going to build now.
Download the Calculator.dll from the source and register
it.
Steps:
- Create a new Project of type Atl COM, name it
ComplexCalculator
and select the type as "dll".
- Insert a new Atl Object, select the Simple Object option and Name it
ComplexMath
.
- Add a new method to the
IComplexMath
interface.
Method Name: Divide
Parameters: [in] int x, [in] int y, [out, retval] int* z
Add the following code:
STDMETHODIMP CComplexMath :: Divide (int x, int y, int *z)
{
*z= x/y;
return S_OK;
}
Do the following changes to CalculatoeEx.idl:
Copy the object section and the interface section of the
Calculator.idl to ComplexCalculator.idl
[
object,
uuid(1E48B0F0-010D-4658-A0B6-70300FDA56F1),
dual,
helpstring("ISimpleMath Interface"),
pointer_default(unique)
]
interface ISimpleMath : IDispatch
{
[id(1), helpstring("method Add")]
HRESULT Add([in] int x, [in] int y,
[out, retval] int* z );
};
In the coclass
part of ComplexCalculator.idl, add the
interface name that we want to aggregate.
Note: Changes that
need to be done are indicated in bolds.
coclass ComplexMath
{
[default] interface IComplexMath;
interface ISimpleMath;
};
Do the following changes to the ComplexCalculator.h:
Copy the CLSID of the SimpleMath
from Calculator_i.c to ComplexCalculator.h
const CLSID CLSID_SimpleMath = {0xF58218E0,0x645A,0x473D,
{0x84,0x4B,0x30,0x78,0x65,
0x03,0x8D,0x9E}};
Do the following change in the COM MAP.
Note: Changes that need to be done are indicated in bolds.
BEGIN_COM_MAP(CComplexMath)
COM_INTERFACE_ENTRY (IComplexMath)
COM_INTERFACE_ENTRY_AGGREGATE (IID_ISimpleMath, ptrUnk)
COM_INTERFACE_ENTRY (IDispatch)
END_COM_MAP ()
Add the following macro, finalconstruct
and release
methods
DECLARE_GET_CONTROLLING_UNKNOWN()
IUnknown* ptrUnk;
HRESULT FinalConstruct()
{
return CoCreateInstance(CLSID_SimpleMath,
GetControllingUnknown(),CLSCTX_ALL,
IID_IUnknown, (void**)&ptrUnk);
}
void FinalRelease()
{
ptrUnk->Release();
}
Search for "Aggregation" in the source code to find code
that is inserted to build the relationship between the "Calculator" and
"ComplexCalculator".
Note: Register the Calculator.dll and ComplexCalculator.dll before using the demo project.