How to call dynamic link library DLL in ASP. NET/C,
Dynamic Link Library(Also called DLL, short for "Dynamic Link Library") is one of the most important elements of Microsoft Windows. When you open a Windows system folder, you will find that there are many DLL files in the folder, windows implements some major system functions in the form of DLL modules.
The dynamic link library cannot be executed directly or receive messages. It is just an independent file, which contains functions (methods) that can be called by programs or other DLL to complete certain operations. Note: C # is generally called a "method"), but these functions are not part of the execution program itself, but loaded as needed based on the needs of the process.
The DLL is only loaded into the virtual space of the process when the application needs it. It becomes part of the calling process. In this case, the DLL can only be accessed by the thread of the process, its handle can be used by the calling process, and the call Process Handle can also be used by the DLL. In the memory, a DLL has only one instance, and its compilation has nothing to do with the specific programming language and compiler. Therefore, you can use the DLL to implement mixed language programming. Any object (including variables) created by the code in the DLL function is owned by the thread or process that calls it.
The following lists some advantages provided by the program when using DLL:
1) use fewer resources
When multiple programs use the same function library, the DLL can reduce the amount of code duplicated in the disk and physical memory. This not only can greatly affect the programs running on the foreground, but also can greatly affect other programs running on the Windows operating system.
2) Promote modular architecture
DLL facilitates the development of modular programs. This helps you develop large programs that require multiple language versions or require a modular architecture. An example of a modular program is a program with multiple modules that can be dynamically loaded at runtime.
3) Simplified deployment and Installation
When the functions in the DLL need to be updated or repaired, you do not need to re-establish the link between the program and the DLL to deploy and install the DLL. In addition, if multiple programs use the same DLL, multiple programs will benefit from the update or repair. This issue may occur more frequently when you use a third-party DLL that is regularly updated or repaired.
The methods for calling DLL in each programming language are different. Here we will only introduce the methods for calling DLL with C. First, you need to know what is managed and what is not managed. It is generally considered that the unmanaged code is mainly developed based on the DLL and activeX Components developed on the win 32 platform, and the managed code is developed based on the. net platform. If you want to learn more about the relationship and differences between hosting and non-hosting, and their operating mechanism, please search for information on your own. This document will not be discussed here.
(1) General method for calling unmanaged functions in DLL
First, the external method should be declared in the C # language source program. The basic form is:
[DLLImport ("DLL file")]
Modifier extern return variable type method name (parameter list)
Where:
DLL file: contains the library file that defines external methods.
Modifier: access modifier, which can be used in addition to abstract when declaring a method.
Return variable type: In the DLL file, you need to call the return variable type of the method.
Method Name: name of the method to be called in the DLL file.
Parameter List: list of methods to be called in the DLL file.
Note: The System. Runtime. InteropServices namespace must be used in the program declaration.
DllImport can only be placed on method declaration.
The DLL file must be located in the current program directory or the system-defined query Path (that is, the Path set by Path in the system environment variable ).
The returned variable type, method name, and parameter list must be consistent with the definition in the DLL file.
To use other function names, you can use the EntryPoint attribute settings, such:
[DllImport ("user32.dll", EntryPoint = "MessageBoxA")]
Static extern int MsgBox (int hWnd, string msg, string caption, int type );
Other optional DllImportAttribute attributes:
CharSet indicates the character set used in the entry point, for example, CharSet = CharSet. Ansi;
SetLastError indicates whether the method retains Win32 "previous error", for example, SetLastError = true;
ExactSpelling indicates whether EntryPoint must exactly match the spelling of the indicated entry point, for example, ExactSpelling = false;
PreserveSig indicates whether the method signature should be retained or converted, for example, PreserveSig = true;
CallingConvention indicates the call convention of the entry point, for example: CallingConvention = CallingConvention. Winapi;
For more information about "data sending and writing" and "sending numbers and logical scalar", see [2].
C # example:
1. Start VS. NET and create a new project named "Tzb". The template is "Windows application ".
2. Double-click the "Button" item in the "Windows Forms" item in the "toolbox" to add a Button to the "Form1" form.
3. Change the button attributes: Name is "B1", Text is "use DllImport To Call DLL to bring up a prompt box", and adjust the button B1 to the appropriate size and move it to the appropriate position.
4. double-click "Form1" in the Class View, open the "Form1.cs" Code view, and enter "using System" on "namespace Tzb. runtime. interopServices; "to import the namespace.
5. in the "Form1.cs [design]" view, double-click the button B1, use the keyword static and extern to declare the method "MsgBox" on the "B1_Click" method, and append the DllImport attribute to this method, here we will use the "MessageBoxA" function in "user32.dll". The specific code is as follows:
[DllImport("user32.dll", EntryPoint="MessageBoxA")]static extern int MsgBox(int hWnd, string msg, string caption, int type);
Then add the following code in the "B1_Click" method to call the method "MsgBox ":
MsgBox (0, "this is the prompt box for calling DLL with DllImport! "," Mug ", 0x30 );
6. Press F5 to run the program and click B1. The following prompt box is displayed:
7. The Code is as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1: Form
{
[DllImport ("user32.dll", EntryPoint = "MessageBoxA")]
static extern int MsgBox2 (int hWnd, string msg, string caption, int type);
public Form1 ()
{
InitializeComponent ();
}
private void Form1_Load (object sender, EventArgs e)
{
}
private void button1_Click (object sender, EventArgs e)
{
MsgBox2 (0, "This is the prompt box popped up by calling DLL with DllImport!", "Challenge Cup", 0x30);
}
private void button2_Click (object sender, EventArgs e)
{
MsgBox2 (0, "This is the prompt box popped up by calling the DLL with DllImport 222222f!", "222222", 0x30);
}
}
}
(2) Dynamic Loading and calling of unmanaged functions in DLL
The preceding figure shows how to use DllImport to call the unmanaged function in DLL, but this is a global function. If the unmanaged function in DLL has a static variable S, each time you call this function, the static variable S automatically adds 1. Results: When a new count is required, the expected results cannot be obtained. The following is an example:
1. Create DLL
1) Start Visual C ++ 6.0;
2) create a "Win32 Dynamic-Link Library" project named "Count ";
3) on the "Dll kind" selection page, select "A simple dll project ";
4) Open Count. cpp and add the following code:
// export function, use "_stdcall" standard call
extern "C" _declspec (dllexport) int _stdcall count (int init);
int _stdcall count (int init)
{// count function, use the parameter init to initialize the static integer variable S, and make S return the value after adding 1.
static int S = init;
S ++;
return S;
}
5) Press "F7" to compile and get Count. dll (in the Debug folder under the project directory ).
2. Use DllImport to call the count function in DLL
1) Open the project "Tzb" and add a button to the "Form1" form.
2) Change the button attributes: Name is "B2", Text is "use DllImport to call the count function in DLL", and adjust the button B1 to the appropriate size and move it to the appropriate position.
3) Open the "Form1.cs" Code view, use the static and extern keywords to declare the method "count", and make it have the implementation of the export function Count from count. dll. The Code is as follows:
[DllImport("Count.dll")]static extern int count(int init);
4) double-click the button B2 in the "Form1.cs [design]" view and add the following code in the "B2_Click" method:
MessageBox. show ("use DllImport to call the count function in DLL. The input value of n is 0, and the result is:" + count (0 ). toString (), "Challenge Cup ");
MessageBox. show ("use DllImport to call the count function in DLL. The input value of n is 10. The result is:" + count (10 ). toString () + "n is not the expected 11 !!! "," Challenge Cup ");
MessageBox. Show ("The result shows that nuse DllImport to call the unmanaged n function in DLL is a global and static function !!! "," Challenge Cup ");
5) copy Count. dll to the binDebug folder of the project "Tzb", Press "F5" to run the program, and click "B2" to bring up the following three prompt boxes:
The 1st prompt boxes show the results of calling "count (0)", and the 2nd prompt boxes show the results of calling "count (10, the results show that "using DllImport to call the unmanaged functions in DLL is a global and static function ". Therefore, sometimes it cannot achieve our goal, so we need to use the method described below: C # dynamic call of functions in DLL.
3. C # dynamically call functions in DLL
Because the use of DllImport in C # is not like dynamic load/unload assembly, so you can only use API functions. In kernel32.dll, functions related to dynamic library calls include:
① LoadLibrary (or AfxLoadLibrary of MFC) to load dynamic libraries.
② GetProcAddress: Get the function to be introduced and convert the symbol name or ID number to the internal DLL address.
③ FreeLibrary (or AfxFreeLibrary of MFC) to release the dynamic link library.
Their prototypes are:
HMODULE LoadLibrary (LPCTSTR lpFileName );
FARPROC GetProcAddress (HMODULE hModule, LPCWSTR lpProcName );
BOOL FreeLibrary (HMODULE hModule );
Now, we can use IntPtr hModule = LoadLibrary ("Count. dll); to obtain the Dll handle, use IntPtr farProc = GetProcAddress (hModule, "_ count @ 4"); to obtain the function entry address.
But how can I call this function after knowing the function entry address? Because there is no function pointer in C # and there is no function pointer call method like C ++ to call the function, we have to use other methods. After research, we found that we can achieve our goal by combining the classes and functions in System. Reflection. Emit and System. Reflection. Assembly. For future convenience and code reuse, we can write a class.
1) write the dld class:
1. open the project "Tzb", open the Class View, right-click "Tzb", select "add" --> "class", and set the class name to "dld ", that is, the start letter of each word in dynamic loading dll.
2. Add the required namespace and declare the parameter transfer method enumeration:
using System.Runtime.InteropServices; // This namespace is required to use DllImport
using System.Reflection; // This namespace is required to use the Assembly class
using System.Reflection.Emit; // This namespace is required to use ILGenerator
Add the following code to the public class dld to declare the parameter transfer method enumeration:
/// <summary>
/// Parameter passing method enumeration, ByValue means value passing, ByRef means address passing
/// </ summary>
public enum ModePass
{
ByValue = 0x0001,
ByRef = 0x0002
}
3. Declare LoadLibrary, GetProcAddress, FreeLibrary, and private variables hModule and farProc:
/// <summary>
/// The prototype is: HMODULE LoadLibrary (LPCTSTR lpFileName);
/// </ summary>
/// <param name = "lpFileName"> DLL file name </ param>
/// <returns> handle to the library module </ returns>
[DllImport ("kernel32.dll")]
static extern IntPtr LoadLibrary (string lpFileName);
/// <summary>
/// The prototype is: FARPROC GetProcAddress (HMODULE hModule, LPCWSTR lpProcName);
/// </ summary>
/// <param name = "hModule"> handle to the library module containing the function to be called </ param>
/// <param name = "lpProcName"> name of the calling function </ param>
/// <returns> function pointer </ returns>
[DllImport ("kernel32.dll")]
static extern IntPtr GetProcAddress (IntPtr hModule, string lpProcName);
/// <summary>
/// The prototype is: BOOL FreeLibrary (HMODULE hModule);
/// </ summary>
/// <param name = "hModule"> Handle of the library module to be released </ param>
/// <returns> whether the specified Dll has been released </ returns>
[DllImport ("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]
static extern bool FreeLibrary (IntPtr hModule);
/// <summary>
/// The handle of the library module returned by Loadlibrary
/// </ summary>
private IntPtr hModule = IntPtr.Zero;
/// <summary>
/// Function pointer returned by GetProcAddress
/// </ summary>
private IntPtr farProc = IntPtr.Zero;
4. added the LoadDll method and reloaded this method for convenience during the call:
/// <summary>
/// load Dll
/// </ summary>
/// <param name = "lpFileName"> DLL file name </ param>
public void LoadDll (string lpFileName)
{
hModule = LoadLibrary (lpFileName);
if (hModule == IntPtr.Zero)
throw (new Exception ("not found:" + lpFileName + "."));
}
If a Dll handle is already loaded, you can use the second version of the LoadDll method:
public void LoadDll (IntPtr HMODULE)
{
if (HMODULE == IntPtr.Zero)
throw (new Exception ("The handle HMODULE of the passed library module is empty."));
hModule = HMODULE;
}
5. Add the LoadFun method and reload this method for the convenience of calling. The code and comments of the method are as follows:
/// <summary>
/// get function pointer
/// </ summary>
/// <param name = "lpProcName"> name of the calling function </ param>
public void LoadFun (string lpProcName)
{// If the handle of the library module is empty, an exception is thrown
if (hModule == IntPtr.Zero)
throw (new Exception ("The handle of the library module is empty, please ensure that the LoadDll operation has been performed!"));
// get function pointer
farProc = GetProcAddress (hModule, lpProcName);
// If a function pointer, an exception is thrown
if (farProc == IntPtr.Zero)
throw (new Exception ("No entry found:" + lpProcName + "entry point to this function"));
}
/// <summary>
/// get function pointer
/// </ summary>
/// <param name = "lpFileName"> contains the name of the DLL file to be called </ param>
/// <param name = "lpProcName"> name of the calling function </ param>
public void LoadFun (string lpFileName, string lpProcName)
{// Get the handle of the library module
hModule = LoadLibrary (lpFileName);
// If the handle of the library module is empty, an exception is thrown
if (hModule == IntPtr.Zero)
throw (new Exception ("not found:" + lpFileName + "."));
// get function pointer
farProc = GetProcAddress (hModule, lpProcName);
// If a function pointer, an exception is thrown
if (farProc == IntPtr.Zero)
throw (new Exception ("No entry found:" + lpProcName + "entry point to this function"));
}
6. added the UnLoadDll and Invoke methods, and the Invoke method was also overloaded:
/// <summary>
/// uninstall Dll
/// </ summary>
public void UnLoadDll ()
{
FreeLibrary (hModule);
hModule = IntPtr.Zero;
farProc = IntPtr.Zero;
}
The above is the method for ASP. NET to call the dynamic link library DLL. I hope it will be helpful for your learning.
Articles you may be interested in:
- How to Use IrisSkin2.dll in C # to beautify the WinForm Interface
- C # convert Word to PDF using Aspose. Words. dll
- C # Call the dll method generated by Matlab
- How to use c # dllimport
- Implementation steps of C ++ and C # mutual dll
- Create DLL dynamic link library text tutorial in C ++ language in Visual Studio
- C # dynamic dll Loading Method
- ASP.net cannot load oci. dll to solve the new law
- C # summary of how to generate DLL files
- C ++ calls the C # DLL Program Implementation Method