|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe ClassFactory is the one of the major concepts in COM. COM provides various ways to control the creation process of the component. Proper understanding of the class factory will help programmers design COM components (i.e. coclass) and their corresponding class objects (i.e. class factories) in a better way. This article will cover the importance of class factories and an example which implements a single class object for multiple COM classes.A class factory is a component whose main purpose is to create other components. A class object is also known as a class factory (class object and class factory are interchangeable) whose main purpose is to create the other components by implementing the standard interface called COM provides a generic way of creating the components. All the components are created in a similar manner.
Object Creation ProcessCoGetClassObject, which provides an interface pointer on a class object associated with a CLSID, needs an entry point in the DLL to create the component’s class factory. In most cases the class factory is implemented along with the component in the same DLL. The entry point is called DllGetClassObject, which creates the class factory. The client initiates the creation process by calling the CoGetClassObject function. The CoGetClassObject looks for a component in the system registry. If it finds the component, it loads the COM server, i.e. DLL, into a memory and then calls DllGetClassObject. The purpose of DllGetClassObject is to create the class object by calling the new operator for a class object. DllGetClassObject queries the class object for the IClassFactory interface, which is returned to the client.
The client, after receiving the As soon as the component is created and the interface (requested) pointer is returned to the client, the purpose of the class object (i.e. to create a component) is achieved and the client can release the class factory for that specific component (CLSID). The client can use the returned pointer on the component to call methods of that component. Every COM DLL server should implement and export a function called Sample code explanationIn the sample code, a single class object has been implemented for multiple COM classes (COM components). There could be a one-to-one mapping between class object and COM component supported. In that case, theDllGetClassObject should create a class object corresponding to the requested CLSID. This case is easy as we can have a multiple if cases in the DllGetClassObject and can call a new operator for the class object corresponding to a requested CLSID.
The purpose of the class object is to create another object (COM component), so the different class factory for different classes will cause the unnecessary duplication of code and makes code less readable. The COM server can be designed in such a way that the single class object should be able to support multiple COM components. This is what has been implemented in the sample code. This has been achieved by the use of the helper function (creator function), which every COM class must support for its creation. There is a structure called struct FactoryInfo
{
const CLSID *pCLSID;
FPCOMPCREATOR pFunc;
};
When the client calls CoGetClassObject, the DllGetClassObject function is called with the requested CLSID as an argument. The DllGetClassObject function looks into the global array of FactoryInfo structures and traverses the array to fetch the address of the creator function, which is mapped to the requested CLSID. The class factory class stores this address in one of its data members, called pCreator, of FPCOMPCREATOR type. This stored address of the creation function in the CFactory class is used in the CreateInstance method of the IClassFactory interface. The address of the creator function is passed to the CFactory at the time of its creation by passing an argument of FPCOMPCREATOR type in the constructor of CFactory class. // Code snippet.
// Traverse a list to find the helper function which corrosponds to
// the requested CLSID.
for (int iCount = 0; iCount < 2; iCount++)
{
if (*gFactoryData[iCount].pCLSID == clsid)
{
break;
}
}
CFactory *pFactory = new CFactory(gFactoryData[iCount].pFunc);
The above code is a part of the DlllGetClassObject function. This function traverses the global array of FactoryData structures and looks for the creation functions address corresponding to the requested CLSID. Once it gets the address of the creator function, it stops traversing the array and passes that address to the constructor of the CFactory class.
The //// Code snippet.
typedef HRESULT (*FPCOMPCREATOR) (const IID&, void**);
class CFactory : public IClassFactory
{
public:
// Rest of the code has been removed from here to make it readable.
CFactory(FPCOMPCREATOR);
~CFactory();
private:
/* This is to store the address of the creator function of the
* COM component with the requested CLSID.
*/
FPCOMPCREATOR pCreator;
long m_cRef;
};
This is a call to the creator function in the CreateInstance method of the CFactory class. hResult = (*pCreator)(iid,ppv);
FPCOMPCREATOR is a synonym for a "pointer to a function which takes const IID & and void** as an argument and returns an HRESULT".
The code has been commented properly to make it self-explanatory. The single class object for multiple COM classes will help you grasp the Class Factory concept in COM.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||