Write a Registration File

Earlier in this chapter, we saw the entries necessary to map an IID to a CLSID that implements the marshalers for that IID, which essentially amounts to the following:


\
Interface
{0002114a-0000-0000-c000-000000000046} = IAnimal
NumMethods = 7
ProxyStubClsid32 = {0002114a-0000-0000-c000-000000000046}

\
CLSID
{0002114a-0000-0000-c000-000000000046} = IAnimal Proxy/Stub Factory
InprocServer32 = c:\inole\chap06\ianimal\ianimal.dll

The strange part about these entries (essentially the contents of CHAP06\IANIMAL\WIN32.REG) is that the CLSID is the same as the IID of the interface. When using the MIDL compiler, you pull in all the CLSID-dependent code, such as DllGetClassObject from RPCRT4.LIB, which means that you can't really set the CLSID to anything you want. Specifically, the standard DllGetClassObject implementation recognizes the IID of any interface contained in the DLL as a suitable CLSID. This allows you to place marshalers for any number of interfaces inside the same DLL.

This little game with the IID and CLSID is an issue only when MIDL is in the picture—it has nothing to do with standard marshaling itself.9 If you implement marshalers manually, you also implement DllGetClassObject and can use any CLSID you want, whether or not it matches an IID.

9 The IID and CLSID do not conflict because they are used in totally different circumstances. An IID is used only in calls to QueryInterface and such and a CLSID is used only in calls to CoGetClassObject and CoCreateInstance. The two simply don't overlap in usage.