Programmers Reference - CLibrary (2)
CLibrary::DynamicCreate
public: CObject* DynamicCreate(const CString &aClassName);
The dynamic create method of the CLibrary is a corner stone in the ConSys system. This method is responsible for handling dynamic loads of classes from libraries. The classes must have been declared dynamic by the DECLARE_DYNAMIC macro. Returns NULL if the method fails.
The problem in the dynamic creation in MFC library, is that it is not truly a dynamic creation. It is still necessary to specify the class name at compile time. The DynamicCreate uses the method used by the CArchive to create classes at runtime. Unfortunately this is undocumented code, and the method may cause problems in newer versions of MFC.
Every MFC extension library has a global list of all classes that is declared dynamic. The main application in turn has a list of the available libraries. The list of libraries is a linked list of CDynLinkLibrary classes. Each of these classes has a classList entry. This entry is a linked list of CRuntimeClasses. When CArchive makes a first time load of a class, it finds the class by name in one of these lists, and creates the class by calling the CRuntimeClass::CreateObject() method. The DynamicCreate method uses the same strategy, but instead of searching from the start of the CDynLinkLibrary list, the DynamicCreate starts with the list for this particular library. If the search fails in the actual library, the DynamicCreate starts a global search for the class.
The functionality of DynamicCreate is located in two methods. The first method (GetRuntimeClass) locates the runtime class of the class given the name of the class. This is the search function of DynamicCreate. Below is a listing of the central parts in the method:
// search app speciffic classes AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); CRuntimeClass* pClass = FindClass(pModuleState->m_classList, aClassName); if( pClass == NULL ){ // search classes in shared DLLs AFX_MODULE_PROCESS_STATE* pState = AfxGetModuleProcessState(); CDynLinkLibrary* pDll = pState->m_libraryList; // for each DLL search while( (pDll != NULL) && (pClass==NULL) ){ pClass = FindClass(pDll->m_classList, aClassName); pDll = pDll->m_pNextDLL; }; }; return pClass;
The FindClass method simply makes a linear search in the library list for the runtime class by comparing the class name to the CRuntimeClass:: m_lpszClassName member variable, and steps through the list by getting the next runtime class from CRuntimeClass::m_pNextClass. The DynamicCreate then simpley creates the class:
CRuntimeClass* pClass = GetRuntimeClass(aClassName); if( pClass != NULL ) { // The class is located, now create. CObject* pObject = pClass->CreateObject(); ASSERT_VALID( pObject ); ASSERT( pObject->GetRuntimeClass()->m_lpszClassName == aClassName ); return pObject; } else { // The class is not located. return NULL; };
It can not be stressed enough that the creation method is undocumented library code from MFC, and can not be expected to be upwards compatible.
References:
Last Modified 10 January 2019