Dynamic PInvoke

CLR provides platform invoke mechanism to enable managed applications to call unmanaged APIs exported in a DLL. Here is a simple example:

using System.Runtime.InteropServices;

public class HelloWorld {
    public static void Main() {
       MessageBox(0, "Hello World", "Platform Invoke Sample", 0);

     [DllImport("user32.dll", CharSet=CharSet.Auto)]
     public static extern int MessageBox(int hWnd, String text, String caption, uint type);

CLR will search the dll in your assembly's directory first, then search the dll in directories listed in PATH environment variable.

If the dll is not in any of those directories, you have to use so called Dynamic PInvoke technique.

There are two known good dynamic PInvoke techniques in .Net framework 1.0 and 1.1:

1. Call LoadLibrary before you call the exported API. Example: http://www.dotnetinterop.com/faq/?q=LoadLibrary

2. Use Reflection.Emit. Example: http://www.msjogren.net/dotnet/eng/samples/dotnet_dynpinvoke.asp

Of course, the newest and greatest Whidbey (.Net framework 2.0) will save the world. It introduces a new mechanism for dynamic PInvoke --- Marshal.GetDelegateForFunctionPointer.

Here is an example:

using System.Runtime.InteropServices;
using System;

public class TestClass
    public static void Main(String[] args)
        IntPtr user32 = LoadLibrary("user32.dll");
        IntPtr procaddr = GetProcAddress(user32, "MessageBoxW");
        MyMessageBox mbx = (MyMessageBox)Marshal.GetDelegateForFunctionPointer(procaddr, typeof(MyMessageBox));
        mbx(IntPtr.Zero, "Hello, World", "A Test Run", 0);

    internal delegate int MyMessageBox(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)]String text, [MarshalAs(UnmanagedType.LPWStr)]String Caption, int type);

    internal static extern IntPtr LoadLibrary(String dllname);

    internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

This example is tested in whidbey beta1.

Comments (8)

  1. th says:

    Is there any way to specify the calling convention to use for the delegate? Or other options available with DllImport (PreserveSig, etc.)?

  2. Nick Parker says:

    Nice, I am going to have to play around with this at home now! 🙂

  3. Anonymous says:

    PInvoke ?????? DLL ??? Load/Unload ????????????

  4. An unmanaged dll can be wrapped in a managed assembly by adding it as a file of a multi-module assembly.

  5. Calling function pointers from C#? Marshal.GetDelegateForFunctionPointer…

Skip to main content