Shaping scalar
First, external methods should be declared in the source program of C# language. Its basic form is: [[DLLImport("DLL file ")] Modifier extern returns the method name (parameter list) of variable type, where: DLL file: the library file containing external methods. Modifier: Access modifier, which can be used when declaring methods other than abstract. Return variable type: In the DLL file, you need to call the return variable type of the method. Method name: the name of the method you need to call in the DLL file. Parameter list: list of methods that need to be called in the DLL file. Note: The system is required. The Runtime.InteropServices namespace in the program declaration. DllImport can only be placed on a method declaration. The DLL file must be located in the current directory of the program or in the system-defined query Path (that is, the path set in the system environment variable PATH). The return variable type, method name and parameter list must be consistent with the definitions in the DLL file. To use other function names, you can set the EntryPoint property, such as: [dllimport ("user32.dll ",entrypoint =" messageboxa ")] static extern int msgbox (in thnd, stringmsg, stringcaption, 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 the "last error" of Win32, for example, SetLastError = true;; ExactSpelling indicates whether the EntryPoint must exactly match the spelling of the indicated entry point, for example, ExactSpelling=false. ; PreserveSig indicates whether the signature of the method should be preserved or transformed, for example: PreserveSig = true;; CallingConvention represents the calling convention of the entry point, such as: calling convention = calling convention.winapi; In addition, please refer to some other articles about "data marshaling" and "marshaling numbers and logical scalars" [2]. C# example: 1. Start VS.NET and create a new project with the name Tzb and the template Windows Application. 2. Double-click the Button item in the Windows Forms item in the toolbox to add a button to the form 1. 3. Change the properties of the button: the name is "B 1" and the text is "Call DllImport to pop up a prompt box". Adjust the button B 1 to a suitable size and move it to a suitable position. 4. Double-click "Form 1" in the class view to open the code view of "Form 1.cs" and enter "Use System". The runtime.interop service is on the "namespace Tzb". Import namespaces. 5. Double-click the button b 1 in Table1. CS [Design] "view, declare the method" MsgBox "with keywords static and extern above the" B 1_Click "method, and attach the DllImport property to the method. We're going to use "user32.dll" here.

[DllImport("user32.dll ",entry point = " MessageBoxA ")]static extern int MsgBox(int hWnd,string msg,string caption,int type);

Then add the following code in the "B 1_Click" method body to call the method "MsgBox":

MsgBox(0, "This is the prompt box that pops up when calling DllImport!" , "Challenge Cup", 0x30); 6. Press "F5" to run the program, and click the button B 1 to pop up the following prompt box: (2) Dynamically load and call the unmanaged function in the DLL. It has been explained above how to call the unmanaged function in DllImport, but this is a global function. If the unmanaged function in the DLL has a static variable S, the static variable S will be automatically incremented by 65438 every time the function is called. As a result, when it is necessary to re-count, the desired result cannot be obtained. The following will illustrate the creation of: 1 DLL 1) starts Visual c++ 6.0;; ; 2) Create a new project named "Win32 dynamic link library"; 3) Select "A Simple dll Project" in the Dll Category selection interface; 4) Open Count.cpp and add the following code:

//Export the function, and call extern "c" _ declspec (DLLExport) int _ stdcallcount (intinit) using "_ stdcallstandard"; Int _ stdcallcount (intinit) {//count function, which initializes the static plastic variable S with the parameter init, and returns static int S = inits++;+after adding 1 to S; Return to s; }

5) Press "F7" to compile and get Count.dll (in the debugging folder under the project directory). 2. Call the count function 1 in DllImport to open the project "Tzb" and add a button to the "Form 1" form. 2) Change the property of the button: the name is "B2" and the text is "Call the counting function in DllImport". Adjust the button B 1 to a suitable size and move it to a suitable position. 3) Open the code view of "Form 1.cs", and declare the method "count" with keywords static and extern, so that it has the realization of exporting the 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 "Form 1.cs[ [Design]" view, and add the following code in the "B2_Click" method body:

MessageBox。 Show ("calls the count function in DllImport, the passed-in parameter is 0, and the result is" +count(0). ToString (), "Challenge Cup"); MessageBox。 Show ("Call the count function in DllImport, the passed-in parameter is 10, and the result is:" +count (10). Tostring ()+"nThe result is not expected 1 1! ! ! " , "Challenge Cup"); MessageBox。 Show ("The result shows that calling unmanaged n function in DllImport is a global static function! ! ! " , "Challenge Cup"); 5) Copy Count.dll to the binDebug folder of the project "Tzb", press "F5" to run the program, and click the B2 button to pop up the following three prompt boxes:

The prompt box 1 shows the result of calling "count(0)", and the second prompt box shows the result of calling "count( 10)", which proves that "calling unmanaged function in DllImport is a global static function". So, sometimes we can't achieve our goal, so we need to use the following methods: C# dynamically calls the functions in the DLL. 3.C# dynamically calls the functions in the DLL. Because DllImport in C# can't dynamically load/unload assembly, it can only use API functions. In kernel32.dll, the functions related to dynamic library call are [3]: ① LoadLibrary (or AfxLoadLibrary of MFC), loading dynamic library. ②GetProcAddress, to obtain the function to be introduced and convert the symbol name or identification number into the internal address of the DLL. ③FreeLibrary (or AfxFreeLibrary of MFC), and release the dynamic link library. Their prototypes are: Hmodule loading library (lpctstr lpfilename); FARPROC GetProcAddress(HMODULE HMODULE,LPCWSTR lpProcName); BOOL free library(HMODULE HMODULE); Now, we can use intptrhmodule = loadlibrary ("count. dll"); To get the handle to the Dll, use intptr farproc = getprocaddress (hmodule, "_ count @ 4"); Gets the entry address of the function. However, after knowing the entry address of the function, how to call this function? Because there is no function pointer in C#, and there is no function pointer to call methods like C++, we have to use other methods. Through research, it is found that we can achieve our goal by combining classes and functions in the system. Reflection.Emit and System.Reflection.Assembly. For the convenience of future use and code reuse, we can write a class. 1) dld writing: 1. Open the project Tzb, open the class view, right-click Tzb and select Add-& gt;; "Class", the class name is set to "dld", that is, the first letter of each word of dynamically loaded dll. 2. Add the required namespaces and declare the enumeration of parameter passing methods:

Use the system. Runtime. interopservices//dllimport requires the System namespace. Reflection; //Use the System to use this namespace. Reflection.Emit uses assembly classes; //This namespace is required to use ILGenerator.

Add the following code above the "public class dld" to declare the enumeration of parameter passing methods:

///& lt; Summarize & gt//Enumerate parameter transfer methods, where ByValue means value transfer and ByRef means address transfer//

///& lt; Summary & gt//The prototype is: HMODULE LOAD Library (lpctstr lpfilename); ///& lt; /summary & gt; ///& lt; Param name = "lpFileName" & gtDLL file name

///& lt; Summary & gt//Load DLL//

Public Void LoadDLL (intptr hm odule) {if (hmodule = = intptr.zero) throw (new exception ("the handle hmodule of the passed-in function library module is empty." )); HModule = HMODULE}5. Add the LoadFun method and overload it for easy calling. The specific code and comments of the method are as follows:

///& lt; Summary & gt///< function pointer//

///& lt; Summary & gt//Uninstall DLL//