Other Unmanaged Functions on mscoree.dll
Although
CorBindToRuntimeEx
is the most commonly used export from mscoree.dll, it is probably not the only one you'll ever use. Table 2-3
Table 2-3. Other Commonly Used Exports from mscoree.dll
|
Hosting Manager Discovery
The COM interfaces in the hosting API are
The discovery of the managers supported by a host and the managers supplied by the CLR are arbitrated through two interfaces named
IHostControl
and
ICLRControl
. As their
IHostControl contains a method called GetHostManager that the CLR uses to determine which managers a host supports, whereas ICLRControl contains a method called GetCLRManager that the host calls to obtain an interface pointer to one of the CLR managers. Figure 2-3 shows the relationship between the host, the CLR, the control interfaces, and the hosting managers. For those managers in which the implementation is split between the CLR and the host, the primary manager interface is always provided by the host. Figure 2-3. IHostControl, ICLRControl, and the hosting managers
Discovering Host-Implemented Managers
Now that we've
Step 1: The Host Supplies a Host Control ClassAfter the host's call to CorBindToRuntimeEx returns, the host initializes an instance of its host control class (that is, a class derived from IHostControl ) and informs the CLR of its existence by calling ICLRRuntimeHost::SetHostControl . It's important to note that the host must do this before ICLRRuntimeHost::Start is calledcalls to SetHostControl that occur after Start have no effect. Given a host-implemented control class such as the following:
class CHostControl : public IHostControl
{
public:
// Methods from IHostControl
HRESULT __stdcall GetHostManager(REFIID riid,
void **ppObject);
// Additional methods, including those from IUnknown, omitted for clarity
};
the code in the host to set the host control object looks like this:
ICLRRuntimeHost *pCLR = NULL;
// Initialize the clr
HRESULT hr = CorBindToRuntimeEx(L"v2.0.40103",
L"wks",
STARTUP_CONCURRENT_GC,
CLSID_CLRRuntimeHost,
IID_ICLRRuntimeHost,
(PVOID*) &pCLR);
// Initialize a new instance of our host control object
CHostControl *pHostControl = new CHostControl();
// Tell the CLR about it...
pCLR->SetHostControl((IHostControl *)pHostControl);
Step 2: The CLR Queries the Host Control Class
After
CorBindToRuntimeEx
returns, the CLR begins the process of setting itself up to run managed code. As part of this initialization, the CLR checks to see whether a host control has been registered (that is, the host called
ICLRRuntimeHost::SetHostControl
). If not, the host does not implement any managers as far as the CLR is
If a valid interface pointer is returned for a given IID, the host is said to implement that manager. If E_NOINTERFACE is returned, the host does not implement that manager. Here's a sample host's implementation of IHostControl::GetHostManager that supports just the memory manager and the assembly loading manager:
HRESULT __stdcall CHostControl::GetHostManager(REFIID riid, void **ppObject)
{
if (riid == IID_IHostMemoryManager)
{
// The CLR is asking for a memory manager. Create an instance of the
// host's memory manager and return it. Note: This snippet assumes
// the host's implementation of the memory manager is in
// a class named CHostMemoryManager
CHostMemoryManager *pMemManager = new CHostMemoryManager();
*ppObject = (IHostMemoryManager *)pMemManager;
return S_OK;
}
else if (riid == IID_IHostAssemblyManager)
{
// The CLR is asking for an assembly loading manager. Create an
// instance of the host's manager and return it. Note: This
// snippet assumes the host's implementation of the Assembly Loading
// Manager is in a class named CHostAssemblyManager
CHostAssemblyManager *pAsmManager = new CHostAssemblyManager();
*ppObject = (IHostAssemblyManager *)pAssemblyManager;
return S_OK;
}
// This host doesn't support any other managers so just return
// E_NOINTERFACE
*ppObject = NULL;
return E_NOINTERFACE;
}
After the series of calls to GetHostManager , the CLR has a complete picture of which managers the host supports. From this point on, the CLR's interaction with the managers goes directly through each manager's primary interface. The host control object's only job is to return managers to the CLR. After that, it's out of the picture. Obtaining CLR-Implemented Managers
As described earlier, the CLR provides a set of managers that
The process a host uses to obtain interface pointers to the CLR-implemented managers is relatively straightforward. First, the host obtains an interface pointer to an ICLRControl by calling ICLRRuntimeHost::GetCLRControl . Next, the host calls ICLRControl::GetCLRManager , passing in the IID of the interface corresponding to the manager of interest. For example, the following code obtains a pointer to the failure policy manager, which is used to customize the way the CLR behaves in the face of resource failures: // Get a pointer to an ICLRControl (pCLR is of type ICLRRuntimeHost *) ICLRControl *pCLRControl = NULL; pCLR->GetCLRControl(&pCLRControl); // Ask for the Failure Policy Manager ICLRPolicyManager *pPolicy = NULL; pCLRControl->GetCLRManager(IID_ICLRPolicyManager, (void **)&pPolicy);
Once the desired interface pointer is returned, the host saves it and calls the methods relevant to the customization it desires. The semantics of when each of the managers can be called and which settings can be configured varies by manager. The rest of this chapter provides an overview of each of the major hosting managers. Details about how to use these managers are provided in
|