T. Nayak

Learning Technologies ,Technic and just sharing…

Managed and Unmanaged code.

Definitions for managed code:

1. Code that is executed by the CLR. Managed code provides information (i.e., metadata) to allow the CLR to locate methods encoded in assembly modules, store and retrieve security information, handle exceptions, and walk the program stack. Managed code can access both managed data and unmanaged data. Managed data—Memory that is allocated and released by the CLR using Garbage Collection. Managed data can only be accessed by managed code

What Is Managed Code?

Managed Code is what Visual Basic .NET and C# compilers create. It compiles to Intermediate Language (IL), not to machine code that could run directly on your computer. The IL is kept in a file called an assembly, along with metadata that describes the classes, methods, and attributes (such as security requirements) of the code you’ve created. This assembly is the one-stop-shopping unit of deployment in the .NET world. You copy it to another server to deploy the assembly there—and often that copying is the only step required in the deployment.
Managed code runs in the Common Language Runtime. The runtime offers a wide variety of services to your running code. In the usual course of events, it first loads and verifies the assembly to make sure the IL is okay. Then, just in time, as methods are called, the runtime arranges for them to be compiled to machine code suitable for the machine the assembly is running on, and caches this machine code to be used the next time the method is called. (This is called Just In Time, or JIT compiling, or often just Jitting.)
As the assembly runs, the runtime continues to provide services such as security, memory management, threading, and the like. The application is managed by the runtime.
Visual Basic .NET and C# can produce only managed code. If you’re working with those applications, you are making managed code. Visual C++ .NET can produce managed code if you like: When you create a project, select one of the application types whose name starts with .Managed., such as .Managed C++ application..

What Is Unmanaged Code?

Unmanaged code is what you use to make before Visual Studio .NET 2002 was released. Visual Basic 6, Visual C++ 6, heck, even that 15-year old C compiler you may still have kicking around on your hard drive all produced unmanaged code. It compiled directly to machine code that ran on the machine where you compiled it—and on other machines as long as they had the same chip, or nearly the same. It didn’t get services such as security or memory management from an invisible runtime; it got them from the operating system. And importantly, it got them from the operating system explicitly, by asking for them, usually by calling an API provided in the Windows SDK. More recent unmanaged applications got operating system services through COM calls.
Unlike the other Microsoft languages in Visual Studio, Visual C++ can create unmanaged applications. When you create a project and select an application type whose name starts with MFC, ATL, or Win32, you’re creating an unmanaged application.
This can lead to some confusion: When you create a .Managed C++ application., the build product is an assembly of IL with an .exe extension. When you create an MFC application, the build product is a Windows executable file of native code, also with an .exe extension. The internal layout of the two files is utterly different. You can use the Intermediate Language Disassembler, ildasm, to look inside an assembly and see the metadata and IL. Try pointing ildasm at an unmanaged exe and you’ll be told it has no valid CLR (Common Language Runtime) header and can’t be disassembled—Same extension, completely different files.
2.Code that targets the common language runtime, the foundation of the .NET Framework, is known as managed code; code that does not target the common language runtime is known as unmanaged code. You can think of the runtime as an agent that manages code at execution time, providing core services such as memory management, thread management, and remoting, while also enforcing strict type safety in the code. The concept of code management is a fundamental principle of the runtime.

3.Managed code supplies the metadata necessary for the CLR to provide services such as memory management, cross-language integration, code access security, and automatic lifetime control of objects. All code based on IL executes as managed code.

4.Code that executes under the CLI execution environment. Managed code uses the execution environment for memory management, object lifetime, and the basic type-system, among other fundamental services.

Managed Code..
1.The Code is Understandable by CLR.
2.It is executed under the instructions of CLR.
3.The code which is done by .net compatible language will be compiled two times.In the first compilation, the compiler will generate MSIL code.Which is known as Managed Code.

UnManaged Code..
1.The CLR cannot able to understand the code.
2.The CLR cannot instruct the code.
3.The second time compilation is unmanaged code.It is understood only by the machine not by the user.

“Unmanaged code” is a new name for an old concept. Unmanaged code stands for native machine code. Software is typically written in some high-level language such as Pascal, C or C++. These languages are translated into machine code (aka unmanaged code) by the compiler and its companion tools (assembler, linker, librarian, etc). The generated code runs natively on the host processor; that is, the processor directly executes the code generated by the compiler. This approach typically results in fastest code execution, but diagnosing and recovery from errors might be easier in managed code.

Managed code is a new name, but the concept also is pretty old. Today, “managed code” typically stands for the system used by Microsoft .NET, but .NET is just one example of a managed code system. The .NET system takes source code in any of the supported languages (which include C, C++, C#, Pascal, and many others), and translates it into code designed for a virtual machine. The real processor cannot execute this code natively, but it can execute a program which then in turn executes the virtual machine’s codes. The program that executes the virtual machine code is known as the virtual machine. While potentially slower than native code execution, the virtual machine can manage code (!) better than real machines. For example, the virtual machine can supervise memory allocation, automatically handle disposal of unused memory, and provide many other services that a native (unmanaged) application typically must explicitly provide. If the virtual machine does its job correctly, all applications using this virtual machine are likely to benefit.

Virtual machines are also known under other names. In the Java system, the tool is called a JVM, a Java Virtual Machine. In the Microsoft .NET system, the intermediate language is called MSIL (Microsoft intermediate language), which are executed through a Just-in Time MSIL compiler (JIT-compiler). Early implementations of Pascal generated an intermediate code called P-code, executed at runtime through some P-code interpreter. Other forms of managed code exist.

Interoperability (“interop“) is bidirectional, which makes it possible to:

  • Call into unmanaged APIs from managed codeThis can be done for both flat APIs (static DLL exports, such as the Win32 API, which is exposed from DLLs like kernel32.dll and user32.dll) and COM APIs (object models such as those exposed by Microsoft® Word, Excel, Internet Explorer, ActiveX® Data Objects (ADO) and so forth).
  • Expose managed APIs to unmanaged codeExamples of doing this include creating an add-in for a COM-based application like Windows Media® Player or embedding a managed Windows Forms control on an MFC form.
  • Decision Tree for Calling Unmanaged APIs

Decision Tree for Exposing Managed APIs

Appendix 1: Crossing the Interoperability Boundary

Calling a Flat API: Step by Step

Figure 3. Calling a Flat API

  1. Get LoadLibrary and GetProcAddress.
  2. Build a DllImport stub from the signature containing the target address.
  3. Push callee-saved registers.
  4. Set up a DllImport frame, and push it onto the stack of frames.
  5. If temporary memory is allocated, initialize a clean-up list for rapid freeing when the call completes.
  6. Marshal parameters. (This could allocate memory.)
  7. Change Garbage Collection mode from cooperative to preemptive, so a Garbage Collection can occur at any time.
  8. Load the target address and call it.
  9. If SetLastError bit is set, call GetLastError and store the result in a thread abstraction stored in Thread Local Storage.
  10. Change back to cooperative Garbage Collection mode.
  11. If PreserveSig=false and the method returned a failure HRESULT, throw an exception.
  12. If no exception was thrown, back-propagate out and by-ref parameters.
  13. Restore the Extended Stack Pointer to its original value to account for caller-popped arguments.

Calling a COM API: Step by Step

Figure 4. Calling a COM API

  1. Build a managed-to-unmanaged stub from the signature.
  2. Push callee-saved registers.
  3. Set up a managed-to-unmanaged COM Interop frame, and push it onto the stack of frames.
  4. Reserve space for temporary data used during the transition.
  5. If temporary memory is allocated, initialize a clean-up list for rapid freeing when the call completes.
  6. Clear floating-point exception flags (x86 only).
  7. Marshal parameters. (This could allocate memory.)
  8. Retrieve the correct interface pointer for the current context inside the Runtime Callable Wrapper. If the cached pointer cannot be used, call QueryInterface on the COM component to obtain it.
  9. Change Garbage Collection mode from cooperative to preemptive, so a Garbage Collection can occur at any time.
  10. From the vtable pointer, index by the slot number, get the target address, and call it.
  11. Call Release on the interface pointer if QueryInterface was previously called.
  12. Change back to cooperative Garbage Collection mode.
  13. If the signature is not marked PreserveSig, check for failure HRESULT and throw an exception (potentially filled with IErrorInfo information).
  14. If no exception was thrown, back-propagate out and by-ref parameters.
  15. Restore the Extended Stack Pointer to the original value to account for caller-popped arguments.

Calling a Managed API from COM: Step by Step

Figure 5. Calling a Managed API from COM

  1. Build an unmanaged-to-managed stub from the signature.
  2. Push callee-saved registers.
  3. Set up an unmanaged-to-managed COM Interop frame, and push it onto the stack of frames.
  4. Reserve space for temporary data used during the transition.
  5. Change Garbage Collection mode from cooperative to preemptive so a Garbage Collection can occur at any time.
  6. Retrieve the COM callable wrapper (CCW) from the interface pointer.
  7. Retrieve the managed object inside the CCW.
  8. Transition appdomains, if required.
  9. If an appdomain is without full trust, perform any link demands that the method might have against the target appdomain.
  10. If temporary memory is allocated, initialize a clean-up list for rapid freeing when the call completes.
  11. Marshal parameters. (This could allocate memory.)
  12. Find the target-managed method to call. (This involves mapping interface calls to the target implementation.)
  13. Cache the return value. (If it is a floating point return value, get it from floating point register.)
  14. Change back to cooperative Garbage Collection mode.
  15. If an exception was thrown, extract its HRESULT to return, and call SetErrorInfo.
  16. If no exception was thrown, back-propagate out and by-ref parameters.
  17. Restore the Extended Stack Pointer to the original value to account for caller-popped arguments.

Leave a comment