Potty Little Details

Just another WordPress.com weblog

Archive for the ‘Framework’ Category

Serializing and Deserializing… How??

leave a comment »

      To make things easier for a formatter, the Framework Class Library offers a FormatterServices type in the System.Runtime.Serialization namespace. This type has only static methods in it and no instances of the type may be instantiated. The following steps describe how a formatter automatically serializes an object whose type has the SerializableAttribute attribute applied to it:

  1. The formatter calls FormatterServices’ GetSerializableMembers method:
    public static MemberInfo[] GetSerializableMembers(Type type);
    

    This method uses reflection to get the type’s instance fields (excluding any fields marked with the NonSerializedAttribute attribute). The method returns an array of MemberInfo objects, one for each serializable instance field.

  2. The object being serialized and the array of System.Reflection.MemberInfo objects is then passed to FormatterServices’ static GetObjectData method:
    public static Object[] GetObjectData(Object obj,
        MemberInfo[] members);
    

    This method returns an array of Objects where each element identifies a field in the object being serialized. This Object array and the MemberInfo array are parallel. That is, element 0 in the Object array is the value of the member identified by element 0 in the MemberInfo array.

  3. The formatter writes the assembly’s identity and the type’s full name to the byte stream.
  4. Finally, the formatter then enumerates over the elements in the two arrays, writing each member’s name and value to the byte stream.

      The following steps describe how a formatter automatically deserializes an object whose type has the SerializableAttribute attribute applied to it.

  1. The formatter reads the assembly’s identity and full type name from the byte stream. If the assembly is not currently loaded into the AppDomain, it is loaded now (as described earlier). If the assembly can’t be loaded, a SerializationException exception is thrown and the object cannot be deserialized. If the assembly is already loaded, the formatter passes the assembly identity information and the type’s full name to FormatterServices’ static GetTypeFromAssembly method, as you can see here:
    public static Type GetTypeFromAssembly(Assembly assem,
                                           String name);
    

    This method returns a System.Type object, indicating the type of object that is being deserialized.

  2. The formatter calls FormatterServices’ static GetUninitializedObject method:
    public static Object GetUninitializedObject(Type type);
    

    This method allocates memory (all bytes are initialized to null or 0) for a new object, but does not call a constructor for the object.

  3. The formatter now constructs and initializes a MemberInfo array like it did before by calling FormatterServices’ GetSerializableMembers method. This method returns the set of fields that were serialized and that now will need to be deserialized.
  4. The formatter creates and initializes an Object array from the data contained in the byte stream.
  5. The reference to the newly allocated object, the MemberInfo array, and the parallel Object array of field values is passed to FormatterServices’ static PopulateObjectMembers method, like so:
    public static Object PopulateObjectMembers(Object obj,
        MemberInfo[] members, Object[] data);
    

    This method enumerates over the arrays, initializing each field to its corresponding value. At this point, you can be sure the object has been completely deserialized.

Written by oneil

September 15, 2008 at 3:23 pm

Posted in Framework

How the CLR Controls the Layout of a Type’s Fields

leave a comment »

To improve performance, the CLR is capable of arranging the fields of a type any way it
chooses. For example, the CLR might reorder fields in memory so that object references
are grouped together and data fields are properly aligned and packed. However, when
you define a type, you can tell the CLR whether it must keep the type’s fields in the
same order the developer specified them or whether it can reorder as it sees fit.
You tell the CLR what to do by applying the System.Runtime.-
InteropServices.StructLayoutAttribute attribute on the class or structure
you’re defining. To this attribute’s constructor, you can pass LayoutKind.Auto to have
the CLR arrange the fields or LayoutKind.Sequential to have the CLR preserve
your field layout. If you don’t explicitly specify the StructLayoutAttribute on a type
that you’re defining, your compiler selects whatever layout it thinks best.
You should be aware that Microsoft’s C# compiler selects LayoutKind.Auto for
reference types (classes) and LayoutKind.Sequential for value types (structures). It
is obvious that the C# compiler team feels that structures are commonly used when
interoperating with unmanaged code, and for this to work, the fields must stay in the
order defined by the programmer. However, if you’re creating a value type that has
nothing to do with interoperability with unmanaged code, you probably want to override
the C# compiler’s default. Here’s an example:
using System;
using System.Runtime.InteropService;
// Let the CLR arrange the fields to improve performance for this
// value type.
[StructLayout(LayoutKind.Auto)]
struct Point {
Int32 x, y;
}

Written by oneil

September 13, 2008 at 3:27 am

Posted in Framework

Here’s what the new operator does………….

leave a comment »

  • It allocates memory for the object by allocating the number of bytes required for the specified type from the managed heap.
  • It initializes the object’s overhead members. Every object instance has two additional members associated with the instance that the CLR uses to manage the object. The first member is the object’s pointer to the type’s method table, and the second member is a SyncBlockIndex.
  • The type’s instance constructor is called, passing it any parameters (the string “ConstructorParam1″, in the preceding example) specified in the call to new. Although most languages compile constructors so that they call the base type’s constructor, the CLR doesn’t require this call.
  • After new has performed all these operations, it returns a reference to the newly created
    object.

Written by oneil

September 13, 2008 at 3:23 am

Posted in Framework

How Common Language Runtime gets loaded

with one comment

When the compiler/linker creates an executable assembly, the following 6-byte x86 stub
function is emitted into the PE file’s .text section:
JMP _CorExeMain
Because the _CorExeMain function is imported from Microsoft’s MSCorEE.dll dynamic-link library, MSCorEE.dll is referenced in the assembly file’s import (.idata) section. MSCorEE.dll stands for Microsoft Component Object Runtime Execution Engine. When the managed EXE file is invoked, Windows treats it just like any normal (unmanaged) EXE file: the Windows loader loads the file and examines the .idata section to see that MSCorEE.dll should be loaded into the process’s address space. Then the loader obtains the address of the _CorExeMain function inside MSCorEE.dll and fixes up the stub function’s JMP instruction
in the managed EXE file. The process’s primary thread begins executing this x86 stub function, which immediately jumps to _CorExeMain in MSCorEE.dll. _CorExeMain initializes the CLR and then looks at
the executable assembly’s CLR header to determine what managed entry point method should execute. The IL code for the method is then compiled into native CPU instructions, and the CLR jumps to the native code (using the process’s primary thread). At this point, the managed application’s code is running. The situation is similar for a managed DLL. When building a managed DLL, the compiler/linker emits a similar 6-byte x86 stub function in the PE file’s .text section for a DLL assembly:
JMP _CorDllMain
The _CorDllMain function is also imported from the MSCorEE.dll, causing the DLL’s .idata section to reference MSCorEE.dll. When Windows loads the DLL, it will automatically load MSCorEE.dll (if it isn’t already loaded), obtain the address of the _CorDllMain function, and fix up the 6-byte x86 JMP stub in the managed DLL. The thread that called LoadLibrary to load the managed DLL now jumps to the x86 stub in the managed DLL assembly, which immediately jumps to the _CorDllMain function in MSCorEE.dll. _CorDllMain initializes the CLR (if it hasn’t already been initialized for the process) and then returns so that the application can continue executing as normal.These 6-byte x86 stub functions are required to run managed assemblies on Windows 98,Windows 98 Standard Edition, Windows Me, Windows NT 4, and Windows 2000 because all
these operating systems shipped long before the CLR became available. Note that the 6-byte stub function is specifically for x86 machines. This stub doesn’t work properly if the CLR is ported to run on other CPU architectures. Because Windows XP and the Windows .NET Server Family support both the x86 and the IA64 CPU architectures, Windows XP and the Windows .NET Server Family loader was modified to look specifically for managed assemblies. On Windows XP and the Windows .NET Server Family, when a managed assembly is
invoked (typically via CreateProcess or LoadLibrary), the OS loader detects that the file contains managed code by examining directory entry 14 in the PE file header. (See IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR in WinNT.h.) If this directory entry exists and is not 0, the loader ignores the file’s import (.idata) section and automatically loads MSCorEE.dll into the process’s address space. Once loaded, the OS loader makes the process’s thread jump directly to the correct function in MSCorEE.dll. The 6-byte x86 stub functions are ignored on machines running Windows XP and the Windows .NET Server Family.
One last note on managed PE files: they always use the 32 bit PE file format, not the 64-bit PE file format. On 64-bit Windows systems, the OS loader detects the managed 32-bit PE file and automatically knows to create a 64-bit address space.(More on Programming Dot net Jeffery Ritcher)

Written by oneil

September 13, 2008 at 2:38 am

Posted in Framework