Calling Win32 DLLs in C#

Written by on Monday 28th November 2011 under C#

How to import methods from a non-managed Win32 API call using Platform Invocation Services (PInvoke). PInvoke allows managed code to call unmanaged methods that are implemented in a DLL.

There are two ways that your C# code can directly call unmanaged code (code which .Net cannot see or have access to), a direct call to a function exported from a DLL or through a call on an interface method on a COM object. This tutorial deals with the former technique; the latter will be covered in a future tutorial.

In order to call an external unmanaged method you must provide .Net with a declaration of the unmanaged method, and a description of how to marshal (use) the parameters and return value to and from the unmanaged code.

This short code sample will invoke a method called "PlaySound" from a DLL called "winmm.dll".

Firstly, you need to add a reference to System.Runtime.InteropServices

using System.Runtime.InteropServices;

Next we need to provide a declaration of the unmanaged code using the DllImport attribute. This tells .Net that the function is contained within a DLL called winmm.dll. This is a Windows built-in file and is found in the system path so you do not need to specify it's full location.

[DllImport("winmm.dll")]
public static extern bool PlaySound(string filename,long hmodule, int dword );

Notice that the methods is static (we do not have a class to instantiate) and we use the extern keyword which informs the compiler that the methods is external to the runtime.

All that is left to do now is to call the methods with parameters. The .Net Framework does not contain the flags header information, so you must either declare them yourself or locate and use the bitwise values. In this example 0x0001 represents the old Win32 flag "SND_FILENAME" and 0x00020000 represents "SND_ASYNC". You can find these values on the Windows API website.

The final code looks like this:

using System;
using System.Runtime.InteropServices;
class PInvokeTest
{
  [DllImport("winmm.dll")]
  public static extern bool PlaySound(string pszSound, UIntPtr hmod, uint fdwSound);
 
  public static void Main()
  {
    bool result;
    result = PlaySound("C:WINDOWSMediaChimes.wav", UIntPtr.Zero, 0x0001 | 0x00020000);
    Console.WriteLine(result);
  }
}

For a list of Win32 functions and parameters please refer to the Windows API Reference on the Microsoft site.

One Response to “Calling Win32 DLLs in C#”

  1. tlhogi mmusisays:

    what are the second and third parameters ( UIntPtr hmod and uint fdwSound);) , what do they mean and how does one know what values to pass them?

Leave a Reply