10.2.2 Call DLLs
There are two methods that can be used to invoke a procedure stored in DLLs.
1. Static call or display load
Use an external declaration clause so that DLLs is loaded before the application begins execution. For example:
function Instr (Sourcestr:pchar; Check:char); Integer; Far External ' usestr ';
Using this method, the program cannot determine the DLLs call at run time. If a particular DLLs is not available at run time, the application cannot execute.
2. Dynamic invocation or implicit loading
Using Windows API functions Loadlibray and GetProcAddress can implement the process of dynamically loading DLLs and invoking them during run time.
Using dynamic invocation is a good choice if the program only calls the DLLs process in one part of the program, or the procedure uses which DLLs, and which process is invoked to determine the actual state of the program's operation.
With dynamic invocation, the program can continue to run even if a DLLs fails to load.
10.2.3 Static Call
When a procedure or function in a DLLs is called statically, external indicates that it is added to the declaration statement of a procedure or function. The invoked procedure or function must take a far-calling pattern. This can be compiled using the far procedure instruction or a {$F +} compilation instruction.
Delphi supports the three invocation methods in traditional Windows dynamic link library programming, which are:
By process/function name
Through the alias of the procedure/function
By sequence number of procedure/function
By invoking the alias of a procedure or function, the user is given the flexibility to program, and the loading speed of the corresponding DLL can be increased through sequential number (INDEX) calls.
10.2.4 Dynamic Invocation
10.2.4.1 API functions in dynamic invocation
There are mainly three Windows API functions used in dynamic invocations, namely: Loadlibrary,getprocaddress and FreeLibrary.
1.Loadlibrary: Load the specified library module into memory
The syntax is:
function LoadLibrary (Libfilename:pchar): Thandle;
LIBFILENAME Specifies the name of the file to load DLLs, and if Libfilename does not contain a path, Windows looks in the following order:
(1) Current catalogue;
(2) Windows directory (a directory containing win.com). function Getwindowdirectory returns the path to this directory;
(3) A Windows system directory (a directory that contains system files such as Gdi.exe). function GetSystemDirectory returns the path to this directory;
(4) A directory containing the current task executable file. Using function GetModuleFileName can return the path of this directory;
(5) A directory listed in the PATH environment variable;
(6) A list of image directories for the network.
If the function succeeds, the instance handle of the loading library module is returned. Otherwise, an error code that is less than Hinstance_error is returned. The meaning of the error code is the following table:
Table 10.2 LoadLibrary returns the meaning of the error code
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Error code meaning
——————————————————————————————————————
0 system memory is not enough, executable file is corrupted or call illegal
2 files were not found
3 paths were not found
5 attempt to dynamically link a task or have a shared or network protection error
6 libraries need to establish separate data segments for each task
8 Not enough memory to start the application
Windows version is incorrect
11 executable file is illegal. Or it is not a Windows application, or a. EXE map
There are mistakes in the image
12 applications are designed for a different operating system (such as the OS/2 program)
13 Application for Ms DOS4.0 design
14 Type of executable file don't know
15 attempting to load a real-mode application (designed for earlier versions of Windows)
16 An attempt to load a second instance of an executable file that contains multiple data segments that can be written
19 An attempt was made to load a compressed executable file. Files must be decompressed before they can be loaded.
20 Dynamic link library file illegal
21 applications require 32-bit extensions
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If the other application has loaded the module into memory before the application invokes a module with LoadLibrary, the LoadLibrary does not load another instance of the module, but instead makes the module's reference count plus 1.
2.GetProcAddress: Picking up the address of a function in a given module
The syntax is:
function GetProcAddress (module:thandle; Procname:pchar): Tfarproc;
The module contains a handle to the called Function Library module, which is returned by LoadLibrary. If you set the module to nil, you want to refer to the current modules.
A procname is a pointer to a string that contains the function name at nil end, or it can also be the order value of a function. If the procname parameter is an order value, the GetProcAddress still returns a value that is not nil if the order value's function does not exist in the module. This will cause confusion. So in most cases, using the function name is a better choice. If you use a function name, the spelling of the function name must match the corresponding spelling in the exports section of the dynamic-link library file.
If the GetProcAddress execution succeeds, return the address of the function entry in the module, or return nil.
3.Freelibrary: Remove library module from memory
The syntax is:
Procedure FreeLibrary (Module:thandle);
Module is the handle of the library module. This value is returned by LoadLibrary.
Because the library module is loaded only once in memory, calling FreeLibrary first minimizes the reference count of the library module. If the reference count is reduced to 0, the module is unloaded.
Each call to LoadLibrary should be called once freelibray to ensure that no additional library modules remain in memory after the application is finished.
10.2.4.2 Dynamic Invocation Examples
For dynamic invocations, we cite a simple example of the following. The system contains two edit boxes altogether. Enter a string in the first edit box, and then enter a character in the second edit box. If the character is contained in the string of the first edit box, the Label box displays information: "in nth position." ", otherwise display information:" Does not contain this character. ”。 As the diagram is the running interface of the program.
Implementation of the input check function in the Edit2 onkeypress Event processing, the list of procedures is as follows.
Procedure tform1.edit2keypress (Sender:tobject; var key:char);
Var
Order:integer;
Txt:pchar;
Pfunc:tfarproc;
Moudle:thandle;
Begin
Moudle: = LoadLibrary (' C:\dlls\example.dll ');
If Moudle > Then
Begin
Edit2.text: = ';
Pfunc: = GetProcAddress (Moudle, ' Instr ');
txt: = Stralloc (80);
txt: = strpcopy (Txt,edit1.text);
Order: = Tinstr (Pfunc) (Txt,key);
If order =-1 Then
Label1.Caption: = ' does not contain this character '
Else
Label1.Caption: = ' located in +inttostr ' (order+1) + ' bit ';
End
FreeLibrary (Moudle);
End
When you take advantage of the function pointer returned by getprocaddess, you must cast the coercion type:
Order: = Tinstr (Pfunc) (Text,key);
TINSTR is a defined function type:
Type
Tinstr = function (Source:pchar; Check:char): Integer;