Welcome to MSDN Blogs Sign in | Join | Help

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);

    [DllImport("kernel32.dll")]
    internal static extern IntPtr LoadLibrary(String dllname);

    [DllImport("kernel32.dll")]
    internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);
}

This example is tested in whidbey beta1.

Published Wednesday, July 14, 2004 6:25 AM by junfeng
Filed under:

Comments

# re: Dynamic PInvoke

Wednesday, July 14, 2004 8:45 AM by th
Is there any way to specify the calling convention to use for the delegate? Or other options available with DllImport (PreserveSig, etc.)?

# re: Dynamic PInvoke

Wednesday, July 14, 2004 10:33 AM by Junfeng Zhang

# re: Dynamic PInvoke

Friday, July 16, 2004 9:45 AM by Nick Parker
Nice, I am going to have to play around with this at home now! :-)

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

Friday, November 12, 2004 1:36 AM by TrackBack
PInvoke ?????? DLL ??? Load/Unload ????????????

# Versioning/Deploying Unmanaged Files

Monday, March 21, 2005 5:03 PM by Suzanne Cook's .NET CLR Loader Notes

# Versioning/Deploying Unmanaged Files

Thursday, April 12, 2007 6:45 PM by Suzanne Cook's .NET CLR Notes

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

# Calling function pointers from C#?

Wednesday, October 08, 2008 9:32 PM by IWebThereforeIAm

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

New Comments to this post are disabled
 
Page view tracker