What is P/Invoke (PInvoke)?

May 8th, 2008 by Dave

P/Invoke, or Pinvoke stands for Platform Invocation Services.  PInvoke is a feature of the Microsoft .NET Frameowrk that allows a developer to make calls to native code inside Dynamic Link Libraries (DLL’s).  When Pinvoking, the .NET framework (or Common Language Routine) will load the DLL and handle the type conversions automatically.  The most common use of P/Invoke is to use a feature of Windows that is only contained in the Win32 API.  The API in Windows is extremely extensive and only some of the features are encapsulated in .NET libraries.  For example, Form.Show(); is really a wrapper for the ShowWindow() API found in shell32.dll.

ShowWindow Declaration API for C#:

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

Note the use of the DllImport attribute.  This attribute, coupled with extern tells the .NET CLR where it can find the native declaration for ShowWindow.  shell32.dll must be registered on the system for this to work properly.

Note: Remember import the System.Runtime.InteropServices namespace!  This is where the [DLLImport] attribute is found.

using System.Runtime.InteropServices;

How are P/Invoked methods called?

Methods that are loaded in using DLLImport are Pinvoked by simply treating them as native .NET functions, and calling them as you would call any other.  Win32 API do tend to use data types that are not used often in .NET, for example – the IntPtr datatype, which is actually a pointer to an integer–in this case, a Window Handle.  nCmdShow is an integer that represents the show command.  But what values of nCmdShow mean what?  These can either be found on MSDN, or PInvoke.net.

C# Constants for ShowWindow in shell32.dll:

  const int        SW_HIDE            = 0;
  const int        SW_SHOWNORMAL      = 1;
  const int        SW_NORMAL          = 1;
  const int        SW_SHOWMINIMIZED   = 2;
  const int        SW_SHOWMAXIMIZED   = 3;
  const int        SW_MAXIMIZE        = 3;
  const int        SW_SHOWNOACTIVATE  = 4;
  const int        SW_SHOW            = 5;
  const int        SW_MINIMIZE        = 6;
  const int        SW_SHOWMINNOACTIVE = 7;
  const int        SW_SHOWNA          = 8;
  const int        SW_RESTORE         = 9;
  const int        SW_SHOWDEFAULT     = 10;
  const int        SW_FORCEMINIMIZE   = 11;
  const int        SW_MAX             = 11;

These constants can be used to call ShowWindow().  So in our origional example of Form.Show(), the P/Invoked way of doing this would be:

ShowWindow(Form.Handle, SW_SHOW);

This isn’t nearly as clean as the Object-Oriented way of using Form.Show(), but this is what is actually happening under the hood of .NET.

Why would I ever want something so overly complicated?

ShowWindow is an example of an API that has been wrapped nicely by the .NET CLR, it is unlikely that you will ever need to import and call it.  But something more useful might be: Deleting a file to the recycle bin.

What resources are out there for PInvoking?

The best resource I have found is PInvoke.net, which has declarations for both VB.NET and C# for commonly used Win32 API.

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Recent Posts
IM Me!
Categories
Meta
Archives