System.Runtime.InteropServices



System.Runtime.InteropServices

The System.Runtime.InteropServices namespace contains classes for managing the interoperation between .NET Framework managed code and native API functions. Since native APIs will vary greatly from one operating system to the next, this namespace will probably contain additional objects that will vary a great deal from one .NET Framework implementation to another. Consult your particular implementation guide.

The attribute DllImportAttribute is applied to a function declaration to tell the compiler that it represents a call to a method in an unmanaged DLL. This attribute contains a selection from the CallingConvention enumeration, specifying the parameter passing and stack cleanup convention used by the function.

When you pass parameters to an unmanaged method, the CLR converts the managed types (for example, System.String) into corresponding unmanaged types (for example, BSTR). Each type has its own default conversion behavior, but you can use the attribute MarshalAsAttribute if you want to change it. This attribute uses the UnmanagedType enumeration to specify the unmanaged type to which you want the managed parameter converted, and the CharSet enumeration specifies the character set to use in marshaling a string. The attributes InAttribute and OutAttribute denote parameters that are marshaled in only one direction, either in (to the called function) or out (from the called function). The absence of either specifies bidirectional marshaling.

Passing structures between managed and unmanaged code is tricky because the packing and element alignment expectations can vary from one unmanaged application to another. The StructLayoutAttribute specifies the basic rules for packing the unmanaged structure, using the LayoutKind enumeration. The FieldOffsetAttribute specifies the offset of individual fields within the structure.

Marshaling memory blocks between .NET's garbage-collected framework and the non-garbage-collected unmanaged code is also tricky. The GCHandle structure contains methods for obtaining pointers to managed memory objects so that they can be used by unmanaged code. The GCHandleType enumeration contains constants used to control this process, for example, one that specifies that a managed memory block is to be pinned in one location until freed.