Apply Now  | Knowledge Base  |  About Us | Locations |  Contact Us
  Knowledge Base

About .NET
LINQ
WPF
About SQL Server 2005
About Business Intelligence
Technical Articles
.NET Articles
SQL Server 2005 Articles
SharePoint 2007 Articles
Business Intelligence Articles
Online Resources





 Live chat by LivePerson



customizingclr_2

Customizing the CLR, Page 2
Back to page 1

Using the ICLRRuntime interface

In this extremely simple example, we won't be launching an application, we will be invoking a method using a function called ExecuteInDefaultAppDomain(). We can certainly invoke a method from an exe file. However, that method cannot be Main(). ExecuteInDefaultAppDomain() requires that the method we invoke accept a string argument and return an integer. As a program entry point, Main() can receive no arguments, or it can receive a string array - it is therefore out-of-the-running as a candidate for ExecuteInDefaultAppDomain(). Similar code is discussed in the excellent Richter book CLR Via C#: Applied Microsoft .Net Framework 2.0 Programming, also from MS Press.

Let's look at the code: 

    1 #include <Windows.h>

    2 #include "assert.h"

    3 #include <MSCorEE.h>

    4 #include <stdio.h>

    5 #include <CorError.h>

    6 

    7 void main(int argc, WCHAR **argv) {

    8    // Load the CLR

    9     //(1)****************************

   10    ICLRRuntimeHost *pClrHost;

   11    HRESULT hr = CorBindToRuntimeEx(

   12       L"v2.0.50727", // desired CLR version (NULL=latest)

   13       NULL,                // desired CLR Optimization (NULL=workstation)

   14       STARTUP_CONCURRENT_GC, // desired startup flags

   15       CLSID_CLRRuntimeHost, // CLSID of CLR

   16       IID_ICLRRuntimeHost,  // IID of ICLRRuntimeHost

   17       (PVOID*) &pClrHost);  // returned COM interface

   18 

   19    //(2) ****************************

   20    // (This is where you would set Host managers)

   21    // (This is where you could get CLR managers)

   22     ICLRControl *pCLRControl;

   23     hr = pClrHost->GetCLRControl(&pCLRControl);

   24 

   25    assert(SUCCEEDED(hr));

   26 // must get this stuff before the CLR is started

   27    ICLRGCManager *ppObject;

   28    hr = pCLRControl->GetCLRManager(

   29                 IID_ICLRGCManager,

   30             (VOID **)    &ppObject);

   31 

   32     //wprintf(L"\n%d\n",hr);

   33     assert(SUCCEEDED(hr));

   34 

   35     //(3) *****************************

   36     // Initialize and start the CLR

   37    pClrHost->Start();

   38 

   39    // Load an assembly and call a static method that

   40    // takes a String and returns an Int32

   41    DWORD retVal;

   42 

   43    hr = pClrHost->ExecuteInDefaultAppDomain(

   44       L"HelloWorld.exe",

   45       L"HelloWorld.Program", L"Hola", L"mundo", &retVal);

   46 

   47 assert(SUCCEEDED(hr));

   48    // Show the result returned from managed code

   49    wprintf(L"\nManaged code returned %d", retVal);

   50 

   51     // (4) *****************************

   52     //hr=ppObject->Collect(0L); //Force a garbage collection

   53     //assert(SUCCEEDED(hr));

   54 

   55     COR_GC_STATS pStats;

   56     pStats.CommittedKBytes=0L;

   57     pStats.GenCollectionsTaken[0]=0L;

   58     pStats.LargeObjectHeapSizeKBytes=0;

   59     pStats.Gen0HeapSizeKBytes=0;

   60     pStats.KBytesPromotedFromGen0=0;

   61     hr= ppObject->GetStats (&pStats);

   62    assert(SUCCEEDED(hr));

   63 

   64     wprintf(L"\nGenCollectionsTaken: %lu",pStats.GenCollectionsTaken[0]);

   65    wprintf(L"\nLargeObjectHeapSizeKBytes: %lu",pStats.LargeObjectHeapSizeKBytes);

   66    wprintf(L"\nCommittedKBytes: %lu",pStats.CommittedKBytes);

   67    wprintf(L"\nGen0HeapSizeKBytes: %lu",pStats.Gen0HeapSizeKBytes);

   68    wprintf(L"\nKBytesPromotedFromGen0: %lu",pStats.KBytesPromotedFromGen0);

   69 

   70 }

 

Code section (1) is similar to that in the previous example, but the interface is the new ICLRRuntimeHost interface. This new interface bears little resemblance to the interface used in the 1.0 and 1.1 versions of the CLR. In particular, the methods for launching an executable assembly are quite distinct. These will be discussed in the next installment of this column. Section (2) of the sample code is not necessary for this example, but we have included it to give you the flavor of customization. In this case, we are obtaining a pointer to the ICLRControl interface, which will then provide us with a pointer to the Garbage Collection Manager. Obtaining these pointers, and other comparable pointers used in CLR customization, must be done before the CLR is started.

In code section (3), we start the CLR and ask it to run a static method for us. As we have noted, ExecuteInDefaultAppDomain() requires that this method receive a string argument and return an Int32. In this example, we assume that the executable file HelloWorld.exe is in the same directory as the host program. If it is not, then the first argument of ExecuteInDefaultAppDomain() must be a fully qualified path. The source for the executable used in this example is included in the appendix, but you should have no difficulty experimenting with your own.

Code section (4) is not necessary for execution; it simply illustrates how to use the pointer we obtained earlier to get detailed information on the status of the Garbage Collector. We create and initialize a COR_GC_STATS structure and pass it to the GetStats method.

Next Month: Creating a Custom AppDomain Manager

Next month we shall build on this example to create a custom AppDomain manager using C#, and lay the foundation for an extensible application.

Appendix

As if the world needs another HelloWorld program:

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 

    5 namespace HelloWorld

    6 {

    7     class Program

    8     {

    9         static void Main()

   10         {

   11             Hola("mundo");

   12 

   13         }

   14         static int Hola(string jrichter)

   15         {

   16             Console.WriteLine("Hola, {0}!", jrichter);

   17             return 0;

   18         }

   19     }

   20 }

 

Source Code

The source code for all 3 examples (Simple Command Host Line, Simple Command Host Line 2, and Hello World) can be found here.

 

About the author:

 

Dan Buskirk had been a research scientist for many years when he left the university labs to participate in a startup venture to design and build databases for medical science. Since that time he has managed a consulting practice specializing in database design and development. Dan balances this with training on Microsoft SQL Server, Microsoft Analysis Services, and .NET programming. His interests include mathematical methods for data mining and computing methods for advanced data categorization on Windows clusters.


   Email this pageprinter-friendly version   

Add the above content to:


 Google   Y! MyWeb   Furl   Simpy   Spurl   Blink  Del.icio.us   Digg  add to technorati Technorati


Microsoft Certification | Visual Studio 2005 | SQL Server 2005 |.NET Framework
HomeApply Now  | Master's Program℠  |  Corporate Services  |  .NET Courses  |  .NET Resources  |  Site Map  |  Trademarks