Поделиться через


How to call C++ DLL from ASP.NET (C#) code?

The problem: normally, you use DLLImport and P/Invoke. However, it only works if DLL is loaded. For normal program you can put it into the same folder as managed executable, and everything will be just fine. Not for ASP.NET, which is compiled into an obscure location, which you would not want to mess up with. Other places like System32 folder are also not a good choice. So, what can you do?

The solution: Actually, people already thought about this problem and found some solutions. See, for example, here. Some people even suggest to create the class dynamically, putting the correct DLLImport attribute value using the reflections. (See. here). However, the reality is much simpler. The only real problem is to ensure that DLL is loaded. One way to do that, is to create a special folder and put it into the PATH environment variable. If you don't like that, you can use the same solution, I did lately, simply load DLL ahead using LoadLibrary. Once it's in memory, the system will not look around on disk and will simply use it.

Code fragments (C#):

Declaration of LoadLibrary:

 [DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string lpFileName);

 [DllImport("kernel32.dll")]
public static extern IntPtr FreeLibrary(IntPtr library);

Declaration of your functions from C++ DLL:

 [DllImport("SampleLib.dll", PreserveSig = true, CharSet = CharSet.Unicode)]
public static extern UInt32 DoStuff(...parameters...);

Loading DLL:

 String DLLPath;
DLLPath = ... full path to your DLL...
IntPtr lib = LoadLibrary(DLLPath);
... now, if lib is equal zero, you failed...

Now you can call it:

 UInt32 res = DoStuff(...);

And after you did what you wanted, don't forget to free it:

 FreeLibrary(lib); // check HRESULT, if that bothers you 

-----

Added 3/8/07: Thanks to PSP (see his comment below), an additional important point is uncovered: DLLImport seems to increase refcount on the library just like LoadLibrary() does. Hence, it looks like you will need to call FreeLibrary() twice. Very odd, but looks real. I wonder, who calls FreeLibrary() when LoadLibrary() is not used?

Comments

  • Anonymous
    September 23, 2006
    Tip/Trick: UpdateProgress Control and AJAX Activity Image Animations [Via: ScottGu ] Vista RC1 Experiences...

  • Anonymous
    March 07, 2007
    Seems to work nicely but the FreeLibrary() never seems to free up and unload the library, try deleting the dll after the FreeLibrary() but before exiting the app, it complains file is in use. Also put a global in the dll and run the Load/function/Free cycle twice and you will find the global retains its value.

  • Anonymous
    March 07, 2007
    FreeLibrary does not really unloads the library, it just tells the system, that it can do so. System is usually conservative about that and does not hurry. In fact, when it comes to something running in ISS, I found it especially conservative for some reason. Sometimes you have to wait 10-15 minutes for IIS to release something it used once.

  • Anonymous
    March 07, 2007
    Just done a bit more research. FreeLibraryy decrements a reference count, when that reaches zero it unmaps the dll from the process. Using the [DllImport] as above seems to create an underlying reference to the library so that calling FreeLibrary once will not free it. Try calling FreeLibrary three times, check the result from the first two FreeLibrary calls, it will be 1 (bool true, ie the call has succeed). The third call returns 0 which means it couldn't unload it. Your IIS behaviour is probably something else.

  • Anonymous
    March 08, 2007
    Cool, although surprising. DLLImport could not do it's job without LoadLibrary, but apparently it is around to mess up with the results... Thanks for the important point.

  • Anonymous
    January 14, 2008
    Nice tutorial. It would  be geat if any body describe how to call dll functions from JAVA.

  • Anonymous
    January 14, 2008
    Nice tutorial. It would  be geat if any body describe how to call dll functions from JAVA.

  • Anonymous
    September 15, 2008
    Please read the following article: http://blog.rednael.com/2008/08/29/MarshallingUsingNativeDLLsInNET.aspx It's an in-depth article about how to use a native DLL (or C++ DLL) in your managed .Net code. The article shows which types are interoperable, how to import a DLL, how to pass strings, how to pass structures and how to de-reference pointers. And C# source code examples are included. regards, Rednael