Daily Archives: October 6, 2009

Interops – Win32 <-> .NET

lamp

Technorati Tags: ,

As discussed in my first post , a common scenario where Interops are needed is accessing a legacy code written using Win32 APIs  in .NET applications for various reasons.

There are two ways that C# code can directly call unmanaged code:

  1. Directly call a function exported from DLL
  2. Call an interface method on a COM object

Luckily Platform Invoke (P/Invoke) service provided by .NET framework supports invoking unmanaged code residing in DLLs to be called in .NET environment.

C# provides a mechanism for providing declarative tags, called attributes which can be placed in certain entities in source code to specify additional information. Information contained in attributes can be ret rived through reflection, or one can use predefined attributes.

Use of DllImport can be made as follows in C# for calling MathFuncimportClass from unmanaged DLL.

[DllImport] public class MathFuncimportClass { … }

In addition to this , we can have few named parameters as well as unnamed(positional) parameters.

[DllImport(“user32.dll”, SetLastError=false,ExactSpelling=false)]
[DllImport(“user32.dll”, ExactSpelling=false,SetLastError=false)]
[DllImport(“user32.dll”)]

For a broader look one must have a reading of DllImportAttribute Members

An excellent info on EntryPoint, Charset, SetLastError and CallingConventions is given on Jason Clark’s post on MSDN Magazine. These are all optional properties in DllImportAttribute.

Data Marshaling

While transferring data between managed and unmanaged combination of code , CLR follows number of rules that one must know so as to tackle any tricky scenario.

While passing parameter to a Windows API function important points needs to be considered as follows

  1. Is the data in a form of integer or float ?
  2. Is the data signed integer or unsigned integer ?
  3. Bitwise presentation of integer data
  4. Floating point data and its precision.

Some special scenarios encountered while marshalling are

  1. Marshaling pointers
  2. Marshaling Opaque pointers
  3. Marshaling Text
  4. Marshaling a complex structure.

A detailed explanation for all these four points is here on MSDN Magazine. Figure 4 on this link also describes actual MSIL signature seen by CLR in various cases.

Copying and Pinning

While CLR performs Data Marshaling , it used two options copying and pinning .

1) While marshaling the data, the interop marshaler can copy or pin the data being marshaled. Copying the data will place a copy of data from one memory to another memory location.

Value types passed by value and by reference explains this scenario.

2) Pinning temporarily locks the data in its current memory location, and thus it is kept away from relocating by CLR’s garbage collector.

A clear scenario can be visualized here at Reference types passed by value and by reference

P/Invoke Interop Assistant

For quickly figuring out the P/Invoke signature for Win32 API function PInvoke Interop Assistant can be very useful. This tool assists developers with conversion from C++ to managed P/Invoke signatures and vice a versa.

This tool is available for download on codeplex website.