Welcome to MSDN Blogs Sign in | Join | Help

Dynamically calling an unmanaged dll from .NET (C#)

This sample is in response to a question left on my previous post, namely how to call an unmanaged dll from managed code when the dll in question isn't known until runtime (for instance, the path is stored in the registry, or an xml file, etc etc).

Apologies if this sample seems a little hurried, but I have another presentation to write and so time is short!

So let's begin.

To start and to refresh our memories, let's create a very basic C++ dll that does very little..... your code should resemble the following (check out my previous post for more info on this):

Header file

extern "C" __declspec(dllexport) int MultiplyByTen(int numberToMultiply);

Source code file

#include "DynamicDLLToCall.h"

int MultiplyByTen(int numberToMultiply)
{
        int returnValue = numberToMultiply * 10;
        return returnValue;
}
 

As you can probably infer from the function name, an int is passed into this function and it will return the number passed in multiplied by ten. Told you it would be simple.

Now comes the more interesting part, actually calling this dll dynamically from your C# source code. There are two Win32 functions that are going to help us do this:

1) LoadLibrary - returns a handle to the dll in question
2) GetProcAddress - obtain the address of an exported function within the previously loaded dll

The rest is rather simple. We use LoadLibrary and GetProcAddress to get the address of the function within the dll we want to call, and then we use the GetDelegateForFunctionPointer static method within the Marshal class to assign this address to a C# delegate that we define. Take a look at the following C# code:

static class NativeMethods
{
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
}

class Program
{
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate int MultiplyByTen(int numberToMultiply);

        static void Main(string[] args)
        {
                IntPtr pDll = NativeMethods.LoadLibrary(@"PathToYourDll.DLL");
                //oh dear, error handling here
                //if (pDll == IntPtr.Zero)

                IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "MultiplyByTen");
                //oh dear, error handling here
                //if(pAddressOfFunctionToCall == IntPtr.Zero)

                MultiplyByTen multiplyByTen = (MultiplyByTen)Marshal.GetDelegateForFunctionPointer(
                                                                                        pAddressOfFunctionToCall,
                                                                                        typeof(MultiplyByTen));

                int theResult = multiplyByTen(10);

                bool result = NativeMethods.FreeLibrary(pDll);
                //remaining code here

                Console.WriteLine(theResult);
        }

The only item worthy of note is the UnmanagedFunctionPointer attribute, which was introduced to version 2.0 of the .NET framework, check out the docs online for more information.

Hope this helps.

Published Tuesday, October 03, 2006 8:06 AM by JonathanSwift

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, October 04, 2006 10:24 AM by Steve

Great follow-up Jonathan. Could you speak to any performance issues related to this type of mechanism. (Marhsalling, some-type-of-reflection, etc.).

# re: Dynamically calling an unmanaged dll from .NET (C#)

Friday, October 06, 2006 12:36 PM by blairio

Thanks for posting a helpful response.  Much appreciated.

PS. Is it safe to assume that at some point you should call the native function FreeLibrary or is that uneccessary?

=B

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, October 10, 2006 2:59 AM by JonathanSwift

Hi Steve and Blairio.

First off, when explicitly calling LoadLibrary FreeLibrary should indeed be called. I'll modify my sample to show this call. As well as this, I'm going to add another post that shows how to free memory that was allocated by unmanaged code that the runtime can't clean up for you. It's quite interesting.

Steve, in terms of performance then whichever way you look at it interop is going to be a hit, no question. The whole topic of performance is very subjective and depends entirely on your targets. What's slow to one application may well be quick to another. Importantly, how slow a particular interop call is seen to be depends on the rest of the request the call is - if database calls/IO etc are in the mix then I've no doubt the interop call will be a very small percentage of the whole, and so even if perceived as 'slow' won't make much difference to the overall performance.

If however you're making an interop call in a tight loop in a request that only performs calculations, you could well feel the hit.

If you have a particular scenario in mind please let me know, and I'll decompose it on here for you and show the most performant way to attack it. There are techniques to use that can help matters.

Thanks guys

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, October 10, 2006 8:47 AM by Steve

Hello again Jonathan,

Thanks for the followup. I didn't really have a particular scenario in mind...just a feeling that there might be some gotchyas there. You always here that kind of thing when talking about reflection and I wasn't sure if they were similar ideas (in the dynamic sense I mean).

Like everything else though, it is a trade-off...and if you can use existing, robust functions maybe the "delay" is worthwhile.

Anyways, thanks again. Looking forward to more.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, October 10, 2006 4:03 PM by JonathanSwift

No worries Steve. After I've put up a post or two showing how to clear unmanaged memory from managed code I'll devote one or two to different aspects of interop performance, and looking at what types to use to increase performance and also refactoring for performance.

Hopefully these will answer some or all of your questions.

Cheers

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, October 18, 2006 6:14 AM by Bas & Joep

Thanks Jonathan! This is exactly what we've been looking for...

# re: Dynamically calling an unmanaged dll from .NET (C#)

Monday, October 30, 2006 7:27 PM by Anonymous

I'm working with a native library that exports a good number of functions.  The problem is that I need to be able to unload the DLL, replace it, and then reload it.  I've noticed that apparently DllImport only does a LoadLibrary() and GetProcAddress() the first time you call an imported function.  So if you FreeLibrary() then LoadLibrary() it is possible it will be loaded into a different address space, so the old function pointers will no longer be valid and you will get access violations.

Currently I've got a class something like this:

class NativeWrapper

{

  NativeWrapper(string filename)

  {

     m_strFileName = filename;

  }

  Load()

  {

     m_hModule = LoadLibrary(m_strFileName);

  }

  Free()

  {

     FreeLibrary(m_hModule);

     m_pfnSomeMethod = null;

  }

  int SomeMethod()

  {

     if(m_pfnSomeMethod == null)

     {

        //pseudocode; you get the idea

        m_pfnSomeMethod = (SomeMethodDelegate)GetProcAddress(m_hModule, "SomeMethod");

     }

     return m_pfnSomeMethod();

  }

}

I have like 30 functions implemented exactly the same way, and I need to do this for about 5 or 6 libraries I am using.  My question is this: is there any way to automate this?  I was thinking of implementing an attribute similar to DllImport, but I don't know where to start or if that is even possible.

The way I understand it, DllImport basically calls LoadLibrary() the first time any function in the library is called, and GetProcAddress() the first time each function is called, and caches the results.  Is DllImport a standard attribute, or does it have some kind of special consideration in the CLR?

# re: Dynamically calling an unmanaged dll from .NET (C#)

Saturday, March 31, 2007 12:05 AM by zawmn

I declare functions for excel export like that

<DllImport("ExcelFG.dll", EntryPoint:="SetCell")> _

       Shared Sub SetCell(ByVal nRow As Integer, ByVal nColumn As Integer, ByVal cellValue As Byte())

       End Sub

       <DllImport("ExcelFG.dll", EntryPoint:="WriteFile")> _

       Shared Sub WriteFile()

       End Sub

And loading the dynamic dll path like that

Dim DLLPath As String

               DLLPath = Server.MapPath("bin\") & "ExcelFG.dll"

               Dim mlib As IntPtr = LoadLibrary(DLLPath)

               If mlib = 0 Then

                   Response.Write("Load Library Fail" & Server.MapPath("bin\") & "ExcelFG.dll")

                   Exit Sub

               End If

And free the loaded library with

FreeLibrary(mlib)

Everything is work fine for my asp application.  But after I call the function, ExcelFG.dll is access deny and can't delete or overwrite.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Thursday, July 26, 2007 6:23 AM by twig

thank you so very much for posting this

its a very elegant fix for this problem.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Monday, July 30, 2007 5:08 AM by vjm

Gr8 work indeed. It has solved my problem.

Thanx a lot.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Monday, October 15, 2007 8:51 AM by euph0ria

very helpful article!!

thank you very much!!

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, December 11, 2007 11:49 AM by alex

add this to the top of your code to use DllImport:

using System.Runtime.InteropServices;

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, March 25, 2008 10:20 PM by mingfei

thank you very much

but your .net framework is 2005,

this 'Marshal.GetDelegateForFunctionPointer' function not provider by vs2003

i want to ynamically call an unmanaged dll from .NET2003 (C#)

you can help me

thanks

my eamil is "mingfei2007316@yahoo.com.cn"

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, April 02, 2008 2:36 PM by Help

I have a FunctionInC (char* &dataPtr), how do I get the data from dataPtr?

Thanks!

# re: Dynamically calling an unmanaged dll from .NET (C#)

Thursday, May 08, 2008 7:21 PM by Mark Collins

Hello,

Great article, thanks for the hardwork. Do you know how to use GetProcAddress with entry point numbers instead of names? I have a .def file containing entry points with noname and only numbers. This page....  http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx

Says that is it possible using a "low-order word". I have no idea what in c# would come close to a low order word. Any help you can offer would be greatly appreciated..

# re: Dynamically calling an unmanaged dll from .NET (C#)

Friday, May 09, 2008 1:07 AM by Sabina

Hi,

Suppose I only know the signature of the native function I am calling at runtime (so I can't explicitly set up the appropriate delegate), is there a way to call the native function?

Any help is appreciated!

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, August 27, 2008 9:55 AM by Richard Howells

Thanks for a handy piece of code.  Just what I wanted.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Friday, October 10, 2008 12:42 AM by Brad Figler

Ahhh, just what I was looking for!!

I was running in to a 126 error when trying to run load my legacy DLL and it turned out that it was because of the dependencies of the DLL itself. The dependencies where loaded in the same directory as the DLL I was trying to load but apparently I need them in the %PATH% in order for it to load properly. I fixed the issue by doing this:

string path = Environment.GetEnvironmentVariable( "PATH" );

path += ";"+"My Path"+"\\";

Environment.SetEnvironmentVariable( "PATH", path );

This sets the environment variable for the process while it is running and has no effect on the system itself.

Hope that saves someone pulling hair out as much hair as I did.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Friday, January 02, 2009 3:32 AM by Taher Hassan

I have a question regarding calling C++ from C#. What about variable types compatibility. In case of int, float, double, and bool, It is good. But, I have one C++ function for printing in a file that uses ostream. When I use it in C# I tried to use streamwriter but it did not work it gives me violation exception. Any tips

Thanks

# re: Dynamically calling an unmanaged dll from .NET (C#)

Tuesday, January 13, 2009 11:36 AM by Nick

Brilliant tutorial Jonathan.

I'd been trying to work out how to do this for ages.

I found it was very important to use dumpbin to find out what the real function names of the dll are as the c compiler had prefixed "_" and postfixed "@0" to all my functions and until I discovered this my code didn't work.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, February 25, 2009 7:35 AM by Yp

When I call FreeLibrary with correct handle of the loaded library, program hangs !!!

What is the reason ?

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, March 04, 2009 1:29 PM by Bernard

I'm also having problems when calling FreeLibrary, the app hangs and when I'm in debug I get "memory couldn't be read at 0x00000" or something like that.

found this which might indicate the problem

http://blogs.msdn.com/jmstall/archive/2007/01/06/Typesafe-GetProcAddress.aspx

# re: Dynamically calling an unmanaged dll from .NET (C#)

Monday, April 20, 2009 1:50 PM by Afein

@ Brad Figler, thanks for your solution to error 126 i definitely was pulling my hair out!

# re: Dynamically calling an unmanaged dll from .NET (C#)

Thursday, April 23, 2009 9:15 AM by Dani

Thank you very much for doing this. I don't have to deal with unmanaged/cli C++ anymore.

# re: Dynamically calling an unmanaged dll from .NET (C#)

Saturday, May 23, 2009 7:32 AM by Roopesh

Hi,

Iam trying to execute the code, that you have provided, it is throwing error message: "An attempt was made to the function with incorrect Format HRESULT:0x80070002B

Environment:

Microsoft Visual Studio 2008

# re: Dynamically calling an unmanaged dll from .NET (C#)

Wednesday, November 25, 2009 11:16 AM by Se7en Soft

Thank you very much for this code snippet. Because of it I have been able to successfully compile my application for any cpu and dynamically load x86/x64 native assemblies as required by the running platform.

Best Regards,

Se7en Soft

# re: Dynamically calling an unmanaged dll from .NET (C#)

Friday, December 11, 2009 12:42 PM by Chad

Great piece of code!

Is there a way to tell your C# project to include the file.. pull it into the bin directory even though you are doing the late binding?  

I am trying to reference a third party app and want to make sure that it gets pulled to the bin to make the the deployment easier.

Any ideas on how to do this?

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker