Modules and COM/DLL Library Support

MMLite provides functions and methods for loading and managing application modules and provides support for the dynamic loading of COM objects.

Modules

A module is usually an entire application or the major part of an application. A module is loaded with IProcess::LoadImage and then managed with run-time library functions and methods of the IModule interface.

The BaseRtl interface provides the following functions and methods to support modules.

GetCurrentModule

 

Gets an interface pointer to the module in the current process.

GetModuleContainsAddr

 

Gets an interface pointer to the module object that contains the specified address.

GetModuleNext

 

Scans the list of loaded modules and gets a pointer to the next module in the list.

IModule::GetArgs

 

Gets the arguments of the specified module.

IModule::GetEntryPoint

 

Gets the value of a module's entry point.

IModule::GetFunctionAddress

 

Gets the address of an exported function.

IModule::GetLocation

 

Gets the module's address location.

IModule::GetName

 

Gets the name of the specified module.

 

COM/DLL Support

Dynamic link library (DLL) is a term used to describe a library which can be linked to as if it were a static library, but for which code and data are not loaded until run time. MMLite does not rely upon or require traditional DLLs, which are strongly dependent upon support from the compiler vendor's linking and loading architecture.

To provide a DLL-like mechanism for dynamically loading and linking to code and data, any MMLite configurations with a loader provide the ability to dynamically load and retrieve interface pointers to COM libraries by binding to them through a special COB (Com OBject) namespace. The Cob Manager, with means of the loader, manages loading and relocating the code, registering the object in the namespace, and later unloading the code when it is no longer being accessed. This mechanism encapsulates many of the functions and methods used with IModule and simplifies dynamically loading, linking, using, and unloading parts of applications.

Implementation of a dynamically loadable COM library is very similar to that of a normal application, with the following differences:

The main function is used as an initialization function; it should perform any global initializations and then immediately return a pointer to the object's root IUnknown interface. Each COM library must, at a minimum, a complete IUnknown interface.

The code must be linked with a flag to tell the loader not to call IProcess::CreateThread for the module after it is loaded.

 

To bind to a dynamic COM object, an application must bind to the object's name through the COB namespace object, which is itself a member of the system's root namespace. If the specified COM object is already loaded into memory and registered in the COB namespace, the Cob Manager will increment the object's reference count and return a pointer to its IUnknown interface. If the object is not already present, the Cob Manager will load it from disk, call its main() function to initialize the library and retrieve its IUnknown pointer, register it in the COB namespace, and finally return an IUnknown interface pointer to the application so that the loading process is transparent to the application.

Due to the implementation of the library loader/unloader, the IUnknown interface returned is not the same pointer as returned by the library's main() function. Instead, it is a proxy interface built on top of it. The application must not simply attempt to cast the IUnknown pointer to get another interface. Rather, it must perform a QueryInterface method on the IUnknown interface to get the correct pointer.

When the application finishes using services or methods in the library, it should call the Release method of the original IUnknown interface to allow unloading of the library's code. The application must not release the IUnknown pointer until after it is finished using the other interfaces inside the library and has released each of them. Failure to follow this rule can cause unloading of the library at an incorrect time.