Platform Invoke

Team-Fly    

Developing XML Web Services and Server Components with Visual C#™ .NET and the .NET Framework, Exam Cram™ 2 (Exam 70-320)
By Amit Kalani, Priti Kalani

Table of Contents
Chapter 9.  Calling Unmanaged Code


The platform invoke (often abbreviated as PInvoke) feature of .NET allows .NET code to call methods from unmanaged libraries such as the Windows API.

To call unmanaged methods from your .NET code, you need to provide the declarations of the method in your .NET code. Because the methods are implemented externally in unmanaged libraries, you should declare the methods in the .NET code with the extern and static keywords.

In addition to declaring the method, you should apply a DllImport attribute of the System.Runtime.InteropServices namespace to the methods. The DllImport attribute tells the CLR where to find the implementation of the external method by specifying the name of the unmanaged library. After the method is declared, you can use it in Visual C# .NET just like you use any other method. Table 9.2 lists the important parameters of the DllImport attribute.

Table 9.2. Important Parameters for the DllImport Attribute

Parameter

Description

CallingConvention

Defines the calling convention to use. The values are specified by the CallingConvention enumeration Cdecl, FastCall, StdCall (default value), ThisCall, and Winapi.

CharSet

Specifies the character set to use. By default, it uses CharSet.Ansi. The other possible values are CharSet.Auto, CharSet.Unicode, and CharSet.None (which is obsolete and behaves as CharSet.Ansi).

EntryPoint

Represents the name of the entry point in the DLL. If the EntryPoint field is not specified, the name of the method is used as the entry point. If the EntryPoint field is passed, you can provide a custom name for the method.

SetLastError

Specifies whether the last error of the Win32 method should be preserved. By default, the value is false.

The following example shows you how to call the GetComputerName() method from the kernel32.dll library by using the DllImport attribute:

  1. Add a new ASP.NET Web Service project named Example9_2 to the existing solution.

  2. Switch to code view. Add the following using directives:

     using System.Text; using System.Runtime.InteropServices; 
  3. Add the following lines of code in the class definition, which indicates that the GetComputerName() method is implemented in kernel32.dll:

     [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern int GetComputerName(     StringBuilder buffer, ref uint size); 

    graphics/note_icon.gif

    In Visual C# .NET, the ref and out keywords are used to pass the reference parameters to Windows 32 API methods.


  4. Add the following Web method definition:

     [WebMethod] public string WebServerName() {     StringBuilder sbBuf = new StringBuilder(129);     UInt32 intLen = (uint) sbBuf.Capacity;     Int32 intRet=0;     // Call the Win API method     intRet = GetComputerName(sbBuf, ref intLen);     return sbBuf.ToString(); } 
  5. Run the project. You should see that a browser is launched showing the test page. Click on the WebServerName method link and click the Invoke button on the method test page. The code displays the name of the Web server where the Web service is run.

graphics/alert_icon.gif

In Visual C# .NET, you should use the StringBuilder object for a Windows API call that expects a string buffer to be modified by the method.


Note the use of the CharSet.Auto parameter in the DllImport attribute of the GetComputerName() method declaration. You might know that many Windows API calls come in two versions, depending on the character set that you're using. For example, GetComputerName() really exists as GetComputerNameA() (for ANSI characters) and GetComputerNameW() (for Unicode characters). The Auto parameter instructs the .NET Framework to use the appropriate version of the API call for the platform where the code is running.

Platform invoke can also handle API calls that require structures as parameters. For example, a call to the GetSystemTime() method fills in a structure that consists of eight members that together indicate the system time. The following code shows you how to represent the structure using the StructLayout attribute in .NET code:

 [StructLayout(LayoutKind.Sequential)] public struct SystemTime {     public ushort year;     public ushort month;     public ushort dayOfWeek;     public ushort day;     public ushort hour;     public ushort minute;     public ushort second;     public ushort millisecond; } [DllImport("Kernel32.dll")] public static extern void GetSystemTime(out SystemTime time); 

You can then call the API using the following code:

 [WebMethod] public SystemTime WebServerTime() {     SystemTime time;     // call the Win32 API method     GetSystemTime(out time);     return time; } 

In this case, the StructLayout attribute tells the Visual C# .NET compiler that the location of the individual fields is sequential within the structure. By using the StructLayout attribute, you can ensure that the .NET Framework constructs the same structure that the API method is expecting to receive.

Many API calls require a Rect structure, which consists of four members that are filled in with the coordinates of a rectangle. In Visual C# .NET, you can declare a structure with explicit byte offsets for each member, which lets you define any structure that the Windows API requires:

 [StructLayout(LayoutKind.Explicit)] public struct Rect {     [FieldOffset(0)] public Int32 left;     [FieldOffset(4)] public Int32 top;     [FieldOffset(9)] public Int32 right;     [FieldOffset(12)] public Int32 bottom; } 

In this case, the StructLayout attribute tells the Visual C# .NET compiler that you'll explicitly specify the location of the individual fields within the structure. The FieldOffset attribute specifies the starting byte of each field within the structure.


    Team-Fly    
    Top


    MCAD Developing XML Web Services and Server Components with Visual C#. NET and the. NET Framework Exam Cram 2 (Exam Cram 70-320)
    Managing Globally with Information Technology
    ISBN: 789728974
    EAN: 2147483647
    Year: 2002
    Pages: 179

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net