Praveen Katiyar' Blog

Learning along the way . . . .

Understanding Late binding

in simplest words, late binding is a technique, in which you can create an instance of a given type, and can invoke its methods, at runtime, without having knowledge of its existence at the compile time.

System.Activator class plays a pivotal role in late binding process.

let us understand, it by creating

  • simple a Class library “MyMathLib” which exposes few methods let say Add, Subtract, Multiply.
  • Console bases client program , that will use this library using the conventional (early binding) method.
  • Console bases client program , that will use this library using the late binding method.

Creating the class library

Create a Class library, let’s name it “MyMathLib” choosing the “Class Library” template from the project wizard. Default project is created with a public class Class1 defined in Class1.cs.

Little house keeping.

rename the Class1 as “MathClass” using the refactor menu.

rename the class1.cs as MathClass.cs

Now define methods Add, Subtract and Multiply for MathClass as shown below.  as shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMathLib
{
    public class MathClass
    {
        public double Add(double dblX, double dblY)
        {
            return (dblX + dblY);
        }

        public double Subtract(double dblX, double dblY)
        {
            return (dblX – dblY);
        }

        public double Multiply(double dblX, double dblY)
        {
            return (dblX * dblY);
        }
    }
}

 

Compile and Build library.

Creating the Application, that will use this library

Create a Console application, let’s name it “TestEarlyBinding” choosing the “Console Application” template from the project wizard. Default project is created.

Little house keeping.

Add Reference of MathLib class library project, created earlier.

Write code in the main function to use this library as shown below.

using System;
using System.Text;

using MyMathLib;

namespace TestEarlyBinding
{
    class Program
    {
        static void Main(string[] args)
        {
            double dblResult = 0;
            double dblX = 200; double dblY = 200;
           
            Console.WriteLine("Tesing early binding");  
           MathClass mathObj = new MyMathLib.MathClass ();
           
            dblResult = mathObj.Add(dblX, dblY);
            Console.WriteLine("Adding {0} and {1} results to {2}", dblX, dblY, dblResult);

            dblResult = mathObj.Subtract (dblX, dblY);
            Console.WriteLine("Adding {0} and {1} results to {2}", dblX, dblY, dblResult);
           
            dblResult = mathObj.Multiply(dblX, dblY);
            Console.WriteLine("Adding {0} and {1} results to {2}", dblX, dblY, dblResult);
        }
    }
}

Compile and build and here is the output.

image

till now, it was default way, we used to do things, but this post is about late binding.

so using the same class library  with late binding, let’s create one more console based project let’s  call it TestLateBidning.

using System;
using System.Text;
using System.Reflection;

namespace TestLateBidning
{
    class Program
    {
        static void Main(string[] args)
        {
            double dblResult = 0;
            double dblX = 200; double dblY = 100;

            Console.WriteLine("Tesing late binding");
           
Assembly assem = null;
           
Console.WriteLine("Loading MyMathLib assembly . . .");
            try
            {
                assem = Assembly.Load("MyMathLib");
            }
            catch (Exception eX)
            {
                Console.WriteLine("Error while loading MyMathLib Error [{0}] \n\nMyMathLib.dll not found in application Folder", eX.Message);
                return;
            }

            Console.WriteLine("Creating Instance of MathClass object . . .");
            Type mathType = assem.GetType("MyMathLib.MathClass");
            object mathObjLB = Activator.CreateInstance(mathType);

            Console.WriteLine("Invoke method [Add] . . .");
            MethodInfo miAdd = mathType.GetMethod("Add");
            dblResult = (double)miAdd.Invoke(mathObjLB, new object[] { 100, 200 });
            Console.WriteLine("Adding {0} and {1} results to {2}", dblX, dblY, dblResult);

            Console.WriteLine("Invoke method [Subtract] . . .");
            MethodInfo miSub = mathType.GetMethod("Subtract");
            dblResult = (double)miSub.Invoke(mathObjLB, new object[] { 100, 200 });
            Console.WriteLine("Subtracting {0} and {1} results to {2}", dblX, dblY, dblResult);

            Console.WriteLine("Invoke method [Multiply] . . .");
            MethodInfo miMul = mathType.GetMethod("Multiply");
            dblResult = (double)miMul.Invoke(mathObjLB, new object[] { 100, 200 });
            Console.WriteLine("Multiply {0} and {1} results to {2}", dblX, dblY, dblResult);
        }
    }
}

Explanation:

Assembly assem = null;
Console.WriteLine("Loading MyMathLib assembly . . .");
try
{
    assem = Assembly.Load("MyMathLib");
}
catch (Exception eX)
{

    . . . . .    
    return

}

Assembly class represents an assembly, which is a valid building block of a common language runtime.

Load method simply loads an assembly, whose name has been provided.

Type mathType = assem.GetType("MyMathLib.MathClass");
object mathObjLB = Activator.CreateInstance(mathType);

Activator class contains methods to create types of object of the specified type, locally or remotely. 

MethodInfo miAdd = mathType.GetMethod("Add");

GetMethod is member function of Type class, that searches the given method name, and returns the MethodInfo, MethodInfo class discovers the attributes of a method access its metadata.

dblResult = (double)miAdd.Invoke(mathObjLB, new object[] { 100, 200 });(mathObjLB, new object[] { 100, 200 });

Invoke method of MethodInfo class simply calls the method, using the required parameters.

similarly other methods (Subtract, Multiply) are discovered and invoked.

build and execute.

image

oops, there was an error, as it could not found the MyMathLib.dll in the test application executable (TestLateBinding.exe) folder.

just copy the MyMathLib.dll to the test application’s executable folder and execute the client again. and you will see what was expected.

image

 

Hope it useful.

Advertisements

April 27, 2014 Posted by | .NET, CodeProject, General | , , , | Leave a comment

Introduction to Device Driver Development

Merely connecting the hardware device to the computer and providing it power is not sufficient for a device to function in a desired manner. In a nutshell, the device driver is a software interface to hardware connected to a computer. It is a trusted part of the operating system. From the user application point of view, the device driver is the abstract connection to the device, and the user application should access the device without having to worry about how the hardware must be controlled,  so a device driver is a piece of software that enables a particular hardware device to function properly. Device driver is so named because it drives the operations of the device, in other words a device driver instructs the hardware device to perform different operations. Almost all externally or internally connected hardware device requires a device driver for its functioning.

  • Device driver program although is a separate piece of program is considered to be a part/extension of  the Operating System.
  • The Operating System becomes dynamically extensible by the use of device drivers.
  • Newer hardware can be added to the system, and installing their respective drivers, without recompiling the operating system, on the other way around, drivers can be updated to run on a newer version of OS.
  • Since device drivers becomes an extension to the OS, it is highly trusted, can perform operations, which are normally not allowed through application programs.
  • In a multitasking environment like windows, hardware devices are a shared resources between all the running programs. allowing hardware access from application program can result in conflict if multiple applications try to access the same device at the same timey.
  • Device driver can not to be integral part of the Operating System. because
      • Each hardware device internally operates in a different way than another.
      • New hardware devices continue to evolve at a rapid rate, so it will not be practical to modify, recompile, and redistribute the OS again and again to accommodate the functionality of a new hardware.
      • By keeping the code for controlling hardware devices in a separate module the operating system remains independent of any particular hardware devices.

Types of device driver

From Functional point of view

Every device driver program does not controls a hardware device. From the functional point of view device driver can be classified in to following categories.

  • A File System driver never interacts with with any physical hardware, The FSD (File System Driver is responsible for handling I/O requests from application, converting these requests to a low level form(Cylinder, Head, Sector request) and passing it to another driver. this another driver actually interacts with the physical storage device.  
  • Another type of driver programs is to write very low level system utilities, because they are trusted part of the system, so they can do things, which are normally not possible in application level code. these activities may include reading/writing directly with I/O Ports, device registers etc.
  • System utilities in particular, sometimes have an additional module in the form of a driver that performs much of the low level activities on the behalf of the utility. System Monitoring utilities are the best example of this category, for example.
      • File Monitor, Disk Monitor, and other similar utilities, normally have two modules, one is a driver at its core, and the other is a GUI application which polls this driver and displays the desired activities.
  • An antivirus program may take help of a driver program to accomplish many of its activities like.
        • Scanning memory areas of all the running processes including the Operating System.
        • providing auto protect feature, where by any program that is being scanned for a virus, if a virus is found, the antivirus program stops the execution of the said program.
  • Driver code can also be used to emulate physical hardware devices. for example there are lot of commercial/freeware/shareware utilities available that can emulate a CDROM device.

From the lens of operating System

with the advent of Windows XP (NT based) OS as a main consumer windows, driver for 16 bit windows and MS-DOS does not make any sense. So when we talk about driver we simply means a Ring–0 driver unless and until explained otherwise. which can be different from functional point of view as explained above

image

Kernel mode (Ring-0) drivers further can be divided into several categories as shown below.

image

Kernel-mode drivers further can be divided into following subcategories.

  • A PnP driver is a kernel-mode driver that understands the Plug and Play protocols of Windows XP. 
  • WDM driver is a PnP driver that understands power-management protocols and is source compatible with both Windows 98/Me and Windows 2000/XP. These type of drivers can be further subcategorized to.
      • Class drivers are those who manage a device belonging to some well-defined class of device.
      • Mini drivers are those, who supply vendor-specific help to a class driver.
      • Monolithic Function drivers are those which embody all the functionality needed to support a hardware device.
      • Filter drivers are those who “filter” the I/O operations for a particular device in order to add or modify behavior.
  • File system drivers implement the standard PC file system model (which includes the concepts of a hierarchical directory structure containing named files) on local hard disks or over network connections. These, too, are kernel-mode drivers.
  • Legacy device drivers are kernel-mode drivers that directly control a hardware device without help from other drivers. This category essentially includes drivers for earlier versions of Windows NT.

What is required for writing a device driver

Drivers for windows use a variety of architectures, and involve understanding of lot of complicated concepts including.

      • Learn hardware details, one must has to to know the details of his hardware environment, memory mapping/addressing, device registers and mapping, accessing them in an architecture independent manner.
      • Learning driver architecture– drivers for windows follow a very specific architecture, that is a very well defined interface for an application to communicate with a driver, again when the Operating System needs to communicate with the driver it follows a different packet driven model.
      • Learn Key Windows Concepts, basically device driver is an extension to the Operating System, writing device drivers needs a lot of details of windows internals.

DDK/WDK

there are several DDK/WDK are available form Microsoft’s website depending version of windows.  the latest version was Windows Driver Kit 7600 (WDK 7600). These kits are available free of cost.

S.N. DDK Version Supported Operating Systems.
1 3790 Windows 2000, Windows XP
2 7600 XP, Vista, Windows Server 2003, Windows 7, Windows Server 2008

Books & online reference.

  • First and foremost, Programming the Windows Driver Model by Walter Oney, can be said to be the Bible for driver development.
  • Programming the Windows Driver for Windows 2000, by Art Baker and Guy Lazano.
  • Windows NT Device Driver by Peter G. Viscarola.
  • Windows Internals by Mark Russinovich

there are several DDK/WDK are available form Microsoft’s website depending version of windows.  the latest version was Windows Driver Kit 7600  (WDK 7600). These kits are available free of cost.

April 11, 2014 Posted by | DDK, Driver Development | , , | Leave a comment