Windows dynamic link library principle (transferred from the Daxion Forum)

xiaoxiao2021-03-05  28

Dynamic Link Library (DLLS) is developed from the concept of C language function libraries and the Pascal library unit. All C language standard library functions are stored in a function library, while users can also create their own libraries with the LIB program. During the link application, the linker is copied from the function code called in the library file and adds these function code to the executable. This method is more conducive to the code based on the function stored in the compiled .Obj file. However, with the emergence of multi-tasking environment such as Windows, the method of the library is too cumbersome. If the screen output, message processing, memory management, dialog, etc., each program has to have its own function, then the Windows program will become very large. Windows development requirements allow several programs that are running to share a single copy of a set of functions. The dynamic link library is in this case. Dynamic Link Library does not need to be compiled or linked, once loaded, the DLLS function can be used by any running application software in the system without having to load another copy of the DLLS function into memory. 1.1. The working principle of the dynamic link library "dynamic link" specifies how DLLS works. For conventional libraries, the linker copies all library functions they need and transmits the exact function address to the program called these functions. For DLLS, the function is stored in a separate dynamic link library file. When you create a Windows program, the link process does not link the DLLS file to the program. This program requires the address of this function until the program runs and calls a function in a DLLS. At this point, Windows looks for the called function in DLLS and transmits its address to the calling program. With this method, DLLS reaches the limit of multiplexing code. Another convenience of the dynamic link library is that the modifications of functions in the dynamic link library can be automatically propagated into all programs that call it without having to make any changes or processing. DLLs not only provides a function reuse mechanism, but also provides a mechanism for data sharing. Any application can share the memory resource block managed by the DLLS loaded in memory. DLLs containing only shared data are called resource files. Such as font files such as Windows, etc. 1.2. The dynamic link library of the Windows system is supported by a large number of dynamic link libraries. This includes Windows API functions (KRNLX86.EXE, USER.EXE, GDI.EXE, ...), various driver files, all kinds of font resource files with .fon and .fot extensions. Windows also provides dedicated DLLs for a certain feature, such as DDE programming DDEML.DLL, Ver.dll, etc. Although the DLLS must be involved when writing a Windows program, but use Delphi, users will not notice this at most. This aspect is because Delphi provides a rich function to enable users to use Windows API directly; on the other hand, even if the Windows API is used, because Delphi reorganizes the API function and other Windows DLLS functions, it is not necessary. Use special call formats. So this chapter focuses on writing and calling user-defined DLLs. Using a traditional Windows programming method to create and use a DLLS is a very headache, as the traditional Windows programming method itself is the same. Users need a series of modifications to define files, engineering files to accommodate the need to create and use DLLs. Delphi's emergence, in this respect, just as in many other respects, the burden of developers is reduced. More exciting is that Delphi uses DLLS to realize the reuse mechanism of the form. Users can store their own forms in a DLLS and call it at any time when needed. 2.1. DLLS Writing In the Delphi environment, writing a DLLS is not much different from writing a general application.

In fact, as a DLL function of the DLLS body, in addition to the management of memory and resources, there is no need for other special means. The real difference is on the project file. In most cases, the user is almost less than the existence of the project file, as it is generally not displayed on the screen. If you want to view the project file, you can open the View menu to select the Project Source item. At this point, the code of the project file will appear in the Code Editor (Code Editor) of the screen. The format of the general engineering document is: Program project title; USES clause; program body and DLLS engineering file format is: library project title; USES clause; exprots clause; program body, there are two points: 1. General The header of the project file with the Program keyword, while the DLLS project file header uses library keywords. Different keyword notification compilers generate different executables. Generating a .exe file with the Program keyword, and use the library keyword is .dll file; 2. If DLLS wants to output functions or procedures for other applications, these functions must be listed in Exports. In the sentence. These functions or process itself must compile with Export compilation instructions. According to the function completed by DLLS, we divide the DLLs three categories: 1. Complete the general function DLLS; 2. DLLS for data exchange; 3. DLLS for the form reuse. In this section, we only discuss DLLs that complete the general functions, and other content will be discussed in the two sections behind. 2.1.1. Steps to Write a general DLLS to prepare a general DLLS steps as follows: 1. Use the Delphi's application template to create a DLLS program framework. For users of Delphi 1.0, because there is no DLLS template,: (1). Create a general application and open the project file; (2). Remove the form and the corresponding code unit; (3). In the project file In the middle, the Program is changed to library, remove the Forms in the USES clause, and add the appropriate library unit (generally sysutils, classes is required), and cut out all the code between the begin ... End. 2. Keep the file with the appropriate file name. At this time, the library will automatically modify the library name; 3. Enter the process, function code. If procedure, the function is prepared for other application calls, then adds Export compilation instructions after the process, the function head; 4. Create an Exports clause, including functions and process names for other application calls. You can use standard instructions Name, Index, Resident to facilitate calls for the process / function; 5. Enter the library initialization code. This step is optional; 6. Compiler, generate dynamic link library files. 2.1.2. The standard in the dynamic link library indicates the output section of the dynamic link library, used three standard instructions: Name, Index, Resident. 1.Name Name After connecting a string constant, as the output name of the process or function. Such as: exports instr name myinstr; other applications will call the process or function with a new name (Myinstr). If you still use the original name (INSTR), a system error is triggered when the program is executed. 2. Index INDEX indicates a sequence number as a process or function. If you do not use index instructions, the compiler is assigned in order. The scope of the number after INDEX is 1 ... 32767. Use Index to accelerate the calling process.

3.Resident uses resident, then the specific output information is always in memory when the DLLS is loaded. This allows for other applications to call the process, it can reduce time overhead than using the name of the DLL. For those processes or functions to be called for those other applications, using the Resident indication is appropriate. For example: Exports Instr Name Myinstr Resident; 2.1.3. Variables in DLLs and Segment A DLLS have their own data segment (DS), so it declares that any variables are all private. The module that calls it cannot use the variable it defines directly. To use the process or function interface to complete. For DLLS, it will never have a chance to use variables declared in the module that calls it. A DLLS does not have its own stack (SS), which uses the stack of the application that calls it. Therefore, the process in the DLL, the function is absolutely not to assume DS = SS. Some languages ​​have this assumption in small mode compilation, but this is to avoid this. Delphi will never produce code of DS = SS, and any runtime library process / function of Delphi does not make this assumption. It is to be noted that if the reader wants to embed the assembly language code, never log in to the same value for SS and DS. 2.1.4. Running time faults in DLLS Because DLLS cannot control the operation of the application, it is difficult to perform an exception handling, so it is very careful when writing DLLs to ensure that it can be performed normally when called. When a runtime error occurs in the DLLS, the corresponding DLLS does not necessarily move from memory (because other applications may be in use with it), and the program of the DLLS is abnormal. The problem caused by this is that when the DLLS has been modified, the memory remains may still be the previous version, and the modified program is not verified. For this problem, there are two solutions: 1. Explicit the DLL out of the memory in the program's exception handling part; 2. Fully exit Windows, then restart, run the corresponding program. Compared with the usual application, the processing of running time in DLL is difficult, and the consequences of the cause are more serious. Therefore, the programmer must be sufficient and thoughtful when writing code. 2.1.5. Write the writing of the current WINDOWS in the library, need two standard functions: libmain and WEP, used to launch and close the DLL. In libmain, the unlocking DLL data segment can be performed, allocate memory, initialization variables, etc., and WEP is called before the DLLS is removed from the memory, which is generally used to make the necessary cleanup work, such as release memory. Delphi implements the functionality of these two standard functions with its own unique way. This is the initialization code to the Begin ... End section in the project file. Compared to traditional Windows programming methods, its main feature is: 1. Initialization code is optional. Some necessary work (such as unlocking data segments) can be done automatically by the system. So most cases the user does not involve; 2. Multiple exit procedure can be set, and then call in sequence when exiting; 3.Libmain and WEP are transparent to the user, and the system is automatically called. The main task of initialization code is: 1. Initialization variables, allocate global memory blocks, login window objects, and the like initialization work. In the (10.3.2) section "Data Transfer between DLLS Realization Application", the global memory block for data sharing is allocated in the initialization code. 2. Set the execution process when DLLS exits. Delphi has a predefined variable EXITPROC to point to the address of the exit process. Users can assign their process names to Exitproc. The system automatically invokes the WEP function, assigns the address pointing to the exitProc to the WEP execution until EXITPROC is NIL.

A program below contains an exit process and a period of initialization code to explain how to properly set the exit process. {$ S-} Uses Wintypes, WinProcs; Var SaveExit: Pointer; ProcedureLibexit; FAR; Begin if EXITCODE = WEP_SYSTEM_EXIT THEN BEGIN {The corresponding process of the system is shut down} ELSE begin {DLL to remove the corresponding processing} End; EXITPROC: = SaveExit; {Restore the original exit process pointer} end; begin {DLL initialization work} saveexit: = exitproc; {Save the original exit process pointer} EXITPROC: = @libexit; {Install new exit process} End. In the initialization code, first save the original exit process pointer to a variable, and then assign the new exit process to EXITPROC. At the end of the custom exit process, the value of ExitProc recovers. Since EXITPROC is a system global variable, it is necessary to recover the original exit process at the end. The exit process libexit uses a system definition variable EXITCODE to log out the status. The value and significance of EXITCODE is as follows: Table 10.1 EXITCODE's value and meaning ━━━━━━━━━━ 取 取 意━━━━━━━ 取 - - --━━━━━━ - - ---------- ----------- WEP_SYSTEM_EXIT Windows Close WEP_FREE_DLLX DLLS is unloaded ━━━━━━━━ 退 退━━━━━━━━ 退 退 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须 必须,,,,,, Set the compilation indication {$ S-}. 2.1.6. Applications Writing General DLLS For example, in the following program we store a function of a string operation to a DLLS to call it when you need it. It should be noted that in order to ensure that this function can be called by the program written by other languages, the string passed as a parameter should be a character array type (ie, PCHAR type), not the end of Object Pascal. SRTING type. The list is as follows: library example; uses sysutils, classes; {Return characters in the string position} Function INSTR (SourceStr: PCHAR; CH: CHAR): Integer; Export; Var Len, i: integer; begin len: = Strlen (Fundstr); for i: = 0 to len-1 do if sourceStr [I] = ch dam result: = i; exit; end; result: = -1; end; exports instr index 1 name 'Myinstr' resident; Begin end. 2.2. Calling DLLs There are two ways to call a process stored in a DLLS. 1. Static calls or display the load uses an external statement clause to put the DLLS to be loaded before the application starts execution.

For example: Function INSTR (SourceStr: Pchar; Check: char); Integer; Far; External 'UseStr'; Using this method, the program cannot determine the call of DLLs in the runtime. If a specific DLLS cannot be used at runtime, the application will not be executed. 2. Dynamic calls or implicit load Use the Windows API function loadLibray and getProcAddress to dynamically load DLLS in the runtime and call the process. If the program only calls the DLLS process, or which DLLS is used, which process is used to call it needs to be judged according to the actual status of the program, then the use of dynamic call is a good choice. Using dynamic calls, even if you load a DLLS fails, the program can continue to run. 2.3. Static call When the process or function is called in a DLLS, the External indicates the addition to the declaration statement of the process or function. The called process or function must be used for a long modulation mode. This can be compiled using the FAR procedure or a {$ f }. Delphi supports three calls in traditional Windows dynamic link library programming, which are: ● By process / function name ● Through the alias of the process / function ● Call the alias from the process / function, give the user Programming provides flexibility, and the load speed of the corresponding DLL can be improved by sequence number (index) call. 2.4.1 The Windows API function used in the dynamic call in the dynamic call is three, namely: LoadLibrary, GetProcaddress, and Freelibrary. 1.LoadLibrary: Fire the specified library module into the memory syntax as: function loadLibrary (libfilename: pchar): thandle; libfilename Specifies the file name to load the DLLS, if the libfilename does not contain a path, Windows looks in the order: (1) Current directory; (2) Windows directory (including win.com directory). Function getWindowdirectory returns the path to this directory; (3) Windows system directory (including system files such as gdi.exe directory). The function getSystemDirectory returns the path to this directory; (4) Contains a directory of the current task executable file. Using the function getModuleFileName can return the path of this directory; (5) Column (5) The directory of the PATH environment variable; (6) The image directory list of the network. If the function is successful, return the instance handle of the loader module. Otherwise, returns a less than the error code for Hinstance_ERROR. The meaning of the error code is as follows: Table 10.2 LoadLibrary The meaning of the error code is ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━ Error code meaning -------------------------------------- 0 system memory is not enough, Executing files are destroyed or calling illegal 2 files that are not found 3 paths that are not found 5 attempts to dynamic links A task or have a shared or network protection error 6 library requires the separation of separate data segments 8 without sufficient memory boot application Program 10 Windows version is incorrect 11 Executive file illegal.

Or is not a Windows application, or in the .exe image has an error 12 application for a different operating system design (such as OS / 2 program) 13 application is MS DOS4.0 design 14 executable type I don't know 15 trial Loading a real mode application (for earlier Windows version) 16 Attempts to load the second example 19 of the executable of multiple data segments containing writable, try to load a compressed executable. The file must be decompressed before it can be installed 20 dynamic link library file illegal 21 applications require 32-bit extension ━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━ 假 假 If the application is called with LoadLibrary to call a module, the other application has put the module into the memory, then LoadLibrary does not load another example of the module, but makes the module. "Quote count" plus 1. 2.GetProcadDress: Picking the address syntax of the function in a given module is: function getProcaddress (Module: thandle; procname: tfarProc; module contains the handle of the called function library module, which is returned by LoadLibrary. If you set the module to NIL, it means to reference the current module. ProcName is a pointer to a string that contains a function name with NIL, or may be the secondary value of a function. If the procName parameter is a secondary value, if the function of the order value does not exist in the module, GetProcAddress returns a non-NIL value. This will cause confusion. Therefore, in most cases the function name is a better choice. If you use a function name, the spelling of the function name must be consistent with the corresponding spelling in the dynamic link library file Exports section. If getProcAddress is successful, return the address at the entry in the module, otherwise returns NIL. 3.Freelibrary: From the middle of the memory module syntax as: Procedure Freelibrary; Module is the handle of the library module. This value is returned by LoadLibrary. Since the library module is only loaded in memory, the free Ibrary first reduces the reference number of the library module. If the reference count is reduced to 0, the module is removed. Each time the loadLibrary should call a freeLibray to ensure that there will be no excess library module remains in memory after the application is over. 2.4.2. Dynamic call example For dynamic calls, we got the following simple example. The system contains two edit boxes. Enter a string in the first editing box, then enter the character in the second editing box. If the character is included in the string of the first edit box, the label box displays information: "Located in the nth.", Otherwise the information: "Does not include this character.". As shown in the figure is the running interface of the program. The implementation of the input check function is in the process of edit2's onkeyPress event processing, as follows.

Procedure tform1.edit2keypress (Sender: Tobject; var); var order: integer; txt: pchar; pfunc: txt: pchar; pfunc: tfarproc; moudle: thandle; begin moudle: = loadingLibrary ('c: /dlls/example.dll'); If Moudle> 32 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 include this character' else label1.caption: = 'is located in' INTOSTR (ORDER 1) 'bit'; END; Freelibrary; END; Mandatory type conversion must be made when using the function pointer returned with getProcadDess: Order: = Tinstr (PFUNC) (TEXT, Key); Tinstr is a defined function type: TYPE TINSTR = Function Source: Pchar; Check: Char): Integer; 3.1. DLLS Global Memory Windows specifies: DLLs do not have any files it open or any global memory block therefor. These objects are owned by applications that are directly or indirectly call DLLs. Thus, when the application is aborted, the open file it has automatically turned off, and its global memory block is automatically released. This means that the files and global memory block variables stored in the DLLS global variable becomes illegal in the case where the DLLs are not notified. This will cause difficulties to other applications that use this DLLS. In order to avoid this, the file and global memory block handle should not be used as a global variable of DLLS, but is passed to the DLLS used as a parameter in the DLLS process or function. Calling DLLS applications should be responsible for their maintenance. However, in certain circumstances, DLLS can also have its own global memory block. These memory blocks must be assigned with GMEM_DDESHARE properties. Such a memory block is maintained until it is released by DLLS to release or DLLS exits. The global memory block managed by DLLS is another way to perform data transfer between applications. Here we will discuss this issue. 3.2. Using DLLS Data Transfer Data Transfer Using DLLS to implement data transfer between applications: 1. Write a DLLS program, which has a global memory block allocated with GMEM_DDESHARE attributes; 2. Server program call DLLS, Write data to the global memory block; 3. The client program calls DLLS to read data from the global memory block. 3.2.1. DLLS for implementing data transmission DLLS for implementing data transmission is basically the same as the general DLLS writing, wherein the particular place is: 1. Define a global variable handle: var hmem: thandle; 2. Definition One process returns the handle of the global variable.

This process is included in the Exports clause. Such as: thandle; export; begin result: = HMEM; END; 3. Allocate global memory blocks in the initialization code: Program list is as follows: Begin Hmem: = GlobalLoc (GMEM_MOVEABLE AND GMEM_DDESHARE, NUM); if HMEM = 0 THEN Messagedlg ('Could Not Allocate Memory', MTWARNING, [Mbok], 0); End. NUM is a predefined constant. The Windows API function GLOBALLOC is used to allocate a memory from the global memory stack and return the handle of the memory block. This function includes two parameters, the first parameter is used to set the allocation flag of the memory block. The allocation marks that can be used are shown in the following table. Table 10.3 Global memory block allocation markers ━━━━━━━━━━━━━━━━━━━━━ 标 标 标 标━━━━━━ - - - 标 - ------- -------------------------- GMEM_DDESHARE assignment can be shared by the application Memory GMEM_DISCARDABLE assigns abandoned memory (only with GMEM_MOVEABLE) GMEM_FIXED Assign fixed memory GMEM_MOVEABLE Allocate Movable Memory GMEM_NOCompact This full stack cannot be compressed or discarded GMEM_NODISCARD This full stack cannot be discarded GMEM_NOT_BANKED assignment cannot be subjected to memory GMEM_NOTIFY notification function. When the memory is abandoned, call the GlobalNotify function GMEM_ZEROINIT to initialize the content of the allocated memory block to zero, ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━ There are two predefined common combinations: ghnd = GMEM_MOVEABLE AND GMEM_ZEROINIT GPTK = GMEM_FIXED AND GMEM_ZEROINIT second parameter to set the number of bytes to be assigned. The allocated byte must be a multiple of 32, so the actually allocated byte number may be larger than the set. Since the module allocated with GMEM_DDeshare is automatically abandoned when the module is terminated, it is not necessary to call GlobalFree Explicitly release memory. 2003-10-20 18:00:00

Publish a review »» »» »» »» »» »»

2003-10-28 13:09:17

Recently, I have extracted another one. I am interested to see http://www.delphibbs.com/keylife/iblog_show.asp?xid=3847

2003-10-31 14:26:59

How do many people like to deal with the application itself when DLL processing classes are programmed in Delphi. But if you can use DLL to process classes, you will make your application have a lot of color. There is no difference in the class and the ordinary class in the DLL. For the DLL process, just remember two points: 1, you cannot allocate memory at one end, and release at the other end; 2, there must be class data export processing, interface processing Should be a standard data type, want to directly handle the category directly in the export function to increase your trouble. Note: You can use interface processing to derive classes, but the OLE may be useful, for general applications, simply. Here is an example: DLL: type TMyDLLClass = class private FData: string; public constructor Create; destructor Destroy; override; property Data: string read FData write FData; end; define several generic interfaces: type TMyDLLOBJ = type Pointer; / General object pointer function CreateMyDLLObj / custom DLL in: TMyDLLOBJ; stdcall; // initialize a class function DoneMyDLLObj (OBJ: TMyDLLOBJ); stdcall; // release and increase your class derivation function: procedure FetchMyDLLData (OBJ: TMyDLLOBJ; Buffer: PChar SIZE: Longint): stdcall; var mydllclass: tmydllclass; begin mydllclass: = TmydllClass (obj); if MydllClass <> nil dam p; e; end; see it, it is so simple, And quite reliable. Most of my applications use this processing, handle the database in the DLL, deliver and process information with a data record. The application is completely separated from the database, to replace the database type, as long as the DLL is updated, the application does not have to change! And no matter what language is used, you can use the powerful part of Delphi (unit structure - making your code easy to manage; TLIST - I use a class, load data table; and string, you can make you Stealing a lot of lazy ...) to make your application easier to develop! 2003-10-31 14:57:37

Use dynamic link library

Introduction: This chapter content: What is DLL. Static link and dynamic link. Why use DLL. Create and use DLL. Display the mode form in the DLL. Use the DLL. DLL in the DLL. DLL in the port and export functions. Exception in the DLL. Tune function. Call the callback function from the DLL. Sharing DLL data in different processes. Exporting the object in the DLL This chapter discusses the Wi N 3 2 dynamic link library, that is, DLL. D L1 is a key component used to write Wi N D O W s applications. This chapter discusses several aspects of using and creating D L1, which gives D l L how to work outlined and discussed how to create and use D L, and you will learn how to transfer D l L and links to different methods of the process and functions they take them. This chapter also includes the use of callback functions and examples of how to implement shared data in different calls processes. 1 What is the DLL dynamic link library is a program module, which includes code, data or resources, and can be shared by other Wi N D O W s applications. One of the main features of the DLL is that the application can transfer code execution at runtime, not when compiling, therefore, multiple applications can share the same D ll code. In fact, the file kernel32.dll, user32.dll, gdi32.dll is the dynamic link library of the core Win32 system. Kernel.dll is responsible for the management of memory, processes, and threads. User32.dll contains some programs, which is a user interface that creates a window and handles Win32 messages. GDI32.DLL is responsible for processing graphics. You will also hear other system DLLs, such as Advapi32.dll and COMDLG32.DLL, which handle object security / registration operations and general dialogs, respectively. Another feature using a dynamic link library is to facilitate the modularity of the application. This simplifies the modification of the application, as usual only needs to modify the DLL instead of the entire application. The Windows environment itself is a typical example of the modular type. Whenever a new device is installed, install a device driver (ie, DLL), enable the device to communicate with Windows. On the disk, a DLL is basically similar to a Windows executable (* .exe). A main difference is that DLL is not a separate executable, although it may contain executable code. The extension of most DLL files is .dll, and some may be .DRV (device driver) ,. SYS (system file) ,. fon, these do not include executable code. Note that Delphi introduces a DLL called a package of packages, which is applied to the Delphi and C programming environment. DLL shares the code through dynamic linking and other applications, which will be discussed later in this chapter. In summary, when an application uses a DLL, the Win32 system ensures that only one DLL copy in the memory, which is implemented by a memory map file. The DLL first is transferred to the global heap of Win32, and then maps to the address space called this DLL process. In the Win32 system, each process is assigned with its own 3 2-bit linear address space. Each process will get a image of the DLL when a DLL is called by multiple processes. Therefore, in 16-bit Windows, program code, data, resources are not shared by the process, and in Win32, the DLL can be seen as a code that is called the DLL process. But this does not mean that if a multi-process calls a DLL, physical memory is assigned each instance of the DLL. The DLL image is placed in the address space of each process by mapping the address space of each process that calls the DLL globally. At least it should be in this way.

The preferred base address of the DLL is set if the DLL is set to the address space of the process, so that the DLL data can be shared. If the DLL base address overlaps with the assigned DLL address, Win32 reassigns the base address. In this way, each reassigned DLL instance has its own physical memory space and exchange file space. This is critical, with a base address to each DLL by using the $ imagebase indicator, which does not cause conflicts or no address overlap. If there are multiple applications to call the same D L1, set a unique base address, so that the high-end address of the process or is in a high-end address of the general D L L (such as a V C L), it will not cause conflicts. General executable files (Exe and DLL) default base address is $ 400000, which means that unless the base address of the DLL is modified, it will conflict with the base site of the main program, so the DLL is not shared between the processes. data. During calling, the DLL does not need to be reassigned or installed because it is saved on the local disk, and the DLL's memory page is directly mapped to the DLL file on the disk. The DLL code does not need to take up the system page file (also called the exchange file). This is why the total number and size of the system submitted may be larger than the system exchange file. You can refer to "Image Base Address" in Delphi's online help, where there is a detailed introduction to the $ imagebase indicator. Some terms about D L L are as follows:. Application, an extension called .exe's Windows program. Performable file, a file containing executable code, which includes .dll files and .exe files. In an example, the executable file that appears in memory is an instance when it comes to the applications and DLLs. The WIN32 system references the instance by an instance handle. For example, if an application runs twice, there will be two instances of the application, and there are two instance handles. When a DLL is being transferred, the example and its corresponding instance handle are simultaneously generated. It should be noted that the examples of the examples mentioned here are not confused. Module, in the 32-bit Windows system, modules and instances can be said to be synonymous. In the 16-bit Windows system, it is a module database to manage the module, one module corresponds to a module handle. In WIN32, every instance of the application has its own address space; so, there is no need to specify an identifier for the module. However, Microsoft still retains its own terminology. Note that the modules and examples are the same concept. The task, Windows is a multi-task (or task switching) environment, so it must be able to reasonably assign system resources and time to run multiple instances. Thus, Windows creates a task database that includes instance handle of the task and other necessary information to implement task switching. The task is an important element for Windows to manage and assign resources and time sections. 9.2 Static link and dynamic link static link refer to the Delphi compiler to compile the functions and procedures to be called into executable code. The function of the function can stay in the application's .dpr file or one unit. When linking the user's application, these functions and procedures become part of the final executable ... It is assumed that there are two applications to call a unit of the same function, of course, these two All applications include the unit in its USES clause. If these two programs are running at the same time, there are two functions in memory. If there is a third such application, there will be an instance of the third function in memory, which will occupy the memory three times. . This small example shows one of the superiority of dynamic links. The function is placed in a DLL through a dynamic link.

Then, if an application is transferred to memory, other applications can share the code by mapping the image of D L1 to the own process memory space. In theory, the final result is an example of only the DLL exists in memory. For dynamic links, the function is connected to the executable of the executable by reference to an external function (which is included in the DLL). The reference can be declared in the application, but usually, the string behind a special introduction (Import) single is the name of the DLL. To use this unit, the application simply adds MaxUnit to its Uses clause. When this program runs, the DLL is automatically transferred to memory, and any programs that need to call the max () are linked to the max () function in this DLL. There are two ways to call the DLL. This is one of them. It is implicitly called, which is to automatically adjust when the application is transferred. . Generally, use the dynamic link library to share code, system resources, hide the implementation code or underlying system routine, design custom controls. The contents of these aspects will be discussed below. 3.1 Shared code, resources and data have been mentioned above in this chapter that shared code is the main purpose of creating a dynamic link library. However, different from the unit's code sharing, the DLL code can be shared by any Windows application, and the sharing of unit code is limited to the Delphi application. In addition, the DLL provides a way for shared resources, such as bitmaps, fonts, icons, etc. These can be placed in a resource file and link directly to the application. If you put these resources in the DLL, you can use many applications without having to load these resources in memory. The code of this line shows that ClientTosreen () is in the dynamic link library user32.dll, its name is ClientTosreen. In 1 6-bit Windows, the DLL has its own data segment, so all the application to call the same DLL The program can access the same global variable and static variable. But in the Win32 system, this is different. Because the DLL image is mapped to the address space of each process, all data of the DLL belongs to the mapped process. It is worth mentioning that although the DLL data cannot be shared, all threads of the same process can be shared because the thread is independent of each other, so when accessing a global variable of a DLL, be careful, prevent causing conflicts. But this does not mean that there is no way to achieve a DLL data between the processes. A technique can create a shared area in memory through a method of memory mapping files. Everything needs to call D L1 to read these data stored in the shared area stored in memory. 3.2 The details of hidden implementations Some time, you may want to hide the details of the routine implementation, and the DLL can achieve this. Regardless of why you want to hide your code, the DLL allows the function to be accessed by the application, and the code details are not appeared, and you have to do just provide others accessing the DLL interface. You may think that Delphi's compilation unit (DCU) can also hide details, but DCUs apply only to Delphi applications, and are also limited by versions. And the DLL is independent of the language, so the created DLL can be called by C , VB, or any other language that supports DLL. The Windows unit is the interface unit of Win32 DLL. Delphi provides a source file for Win32 API, one is the source file Windows.PAS. 3.3 Custom Control Custom Controls are typically placed in the DLL. These controls are different from Delphi custom components. Custom controls are registered under Windows and can be used in any Windows development environment.

Adjip these types of custom controls into the DLL, considering only one instance of the control in memory even if there are multiple applications to use these custom controls. Note that it is too time to advance the custom control to the DLL. Now, Microsoft uses OLE and ACTIVEX controls, and custom controls have rare. 2003-10-31 15:13:22

Method and trick to call DLL in the Delphi environment

The first chapter uses a dynamic link library (DLL) to lift the DLL you will not be unfamiliar, there is a lot of files with a large amount of DLL suffix in Windows, which is an important guarantee that guarantees Windows normal operation and maintenance upgrade. In fact, the DLL is a special executable. It is especially mainly because it is generally not possible to run directly, and the host program can be used, such as a dynamic call of the * .exe program or other DLL. Simply put, in general, the DLL is a collection of compiled functions and processes. There are several reasons for using DLL technology: First, reduce the size of the executable file. A large part of the production of DLL technology is to reduce the size of the executable. When the operating system enters the Windows era, its size has reached several tens of trillions or even hundreds. Imagine if a single executable file system using the DOS era may reach tens of megabytes, this is unacceptable. The solution is to use dynamic link technology to divide a large executable into many small executables. Second, achieve resource sharing. The resource sharing here includes many aspects, the most is the memory sharing, code sharing, and more. Early programmers often encounter such things and write the same code in different programming tasks. This approach is clearly wasting for many times, in order to solve this problem, people have written a variety of libraries. However, due to the different libraries of programming languages ​​and the environment generally universal, and users need these libraries when running the program, it is extremely inconvenient. The appearance of the DLL is like a standard that has been developed, so that these libraries have a unified specification. In this way, the programmer with different programming languages ​​can easily use the DLL written in other programming languages. In addition, the DLL has a prominent feature that is only loaded in memory, which can save limited memory and can serve multiple processes at the same time. Third, easy to maintain and upgrade. A careful friend may find that some DLL files are released. (View the properties of the DLL file can be seen, but not every DLL file is to facilitate maintenance and upgrade. For example, a bug in the early Win95 is that this day cannot be displayed correctly in the leap year. Later, Microsoft released a patch corrected this bug. It is worth mentioning that we did not reload Win95, but used the new version of the DLL instead of the old version of the DLL. (Which DLL file author I can't think of it.) Another common example is the upgrade of the driver. For example, the famous DirectX has been upgraded many times and has now been developed to version 6.0. What is even better, when we try to install a lower version of the DLL, the system will prompt us to avoid human operation errors. For example, when we upgrade a hardware driver, frequent Windows prompts our currently installed drivers than the original driver. Fourth, more secure. The security mentioned here also includes many aspects. For example, the DLL file has a much lower violation of the virus than the ordinary EXE file. In addition, since it is dynamic link, this has brought some of the difficulty of disassembly from "master" "master" that is destroyed. Chapter 2 writes a DLL TOP in Delphi to say so much, and the general is correct. Writing a DLL is actually not a very difficult thing, just pay attention to something is enough. In order to facilitate explanation, we will give an example.

Library Delphi; Uses sysutils, classes; Function TestDLL (i: integer): integer; stdcall; begin result: = i; end; exports testdll; begin end. What is the example above? Friends who are familiar with Delphi can see that the above code and the general Delphi program are basically the same, but there is more stdcall parameters after the TestDll function and declare the TestDll function with the exports statement. As long as the above code is compiled, you can get a dynamic link library called Delphi.dll. Now let's take a look at what you need to pay attention to. First, the function or procedure written in the DLL must add the stdcall call parameters. This call parameter is FAR in the Delphi 1 or Delphi 2 environment. This parameter is changed from Delphi 3 for stdcall, and the purpose is to replace the optimized Register parameter in order to use standard Win32 parameter transfer technology. Forgot to use the stdcall parameter is a common error. This error does not affect the compilation and generation of the DLL, but a very serious error occurs when calling this DLL, resulting in the deadlock of the operating system. The reason is that the register parameter is the default parameter of Delphi. Second, the written function and process should be declared using an Exports statement as an external function. As everyone see, the TestDLL function is declared as an external function. This can make this function to see outside, and the specific method is the "QuickView" feature to view the DLL file. (If there is no "quick view" option to be installed from the Windows CD.) The TestDll function will appear in the ExportTable column. Another very good reason is that if you don't declare this, the function we have written will not be called, this is everyone who is not willing to see. Third, when using a long string type, the variable is referenced to ShareMem. The String type in Delphi is very powerful. We know that the normal string length is 256 characters, but the String type in Delphi can reach 2G by default. (Yes, you don't have a mistake, it is indeed two megabytes.) At this time, if you insist on using the string type parameter, the variable is even logging information, it is to reference the ShareMem unit, and must be the first reference. Being the first referenced unit after the Uses statement. Such examples: Uses ShareMem, Sysutils, Classes; there is a little, in your project file (* .dpr) instead of the unit file (* .pas), do the same job, this point of Delphi comes with help files Did not clear, causing a lot of misunderstandings. If you don't do this, you are very likely to pay the cost of the crash. Avoid using String types is to declare the parameters, variables of the String type as PCHAR or shortstring (eg S: String [10]) type. The same problem occurs when you use a dynamic array, the method of solving is the same as above. The third chapter is easy to call a DLL in Delphi to call a DLL to be more likely to write a DLL. First, give you a static call method, will introduce the dynamic call method and make a comparison on both ways. Similarly, we first raised an example of static calls.

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class (TForm) Edit1: TEdit; Button1: TButton; procedure Button1Click (Sender: TObject); private {Private declarations } Public {public declarations} END; VAR FORM1: TFORM1; IMPLEMENTATION {$ r * .dfm} // The following code is the code for our true handwritten code FUNCTION TESTDLL (i: integer): integer; stdcall; external 'delphi. DLL '; procedure tform1.button1click (sender: TOBJECT); Begin Edit1.Text: = INTTOSTR (Testdll (1)); End; End. In the above example we placed a edit box (Edit) on the form (Edit) and one Button, and write very little code to test our Delphi.dll we have just written. Everyone can see that our unique work is to put the test portion of the TestDll function in the Implementation, and specify the location of Delphi.dll with the External statement. (In this example, the calling program and Delphi.dll are in the same directory.) Is exciting that the TestDLL function we wrote quickly was quickly recognized by Delphi. You can do such an experiment: Enter "TestDLL (", very fast Delphi will use the fly-by prompt to prompt what you should enter, just as simple as we are using other functions defined in Delphi. Notes have the following Some: 1. Call parameters use stdcall. As mentioned earlier, the STDCALL parameters should be used when referenced in the DLL, the cause is the same as mentioned earlier. Second, use the External statement to specify the called DLL file The path and name. As everyone saw, we specify the name of the DLL file to be called in the External statement. No write path is because the DLL file and the main program of calling it in the same directory. If the DLL file is C:, then we can write the above reference statement as External 'C: Delphi.dll'. Note that the file suffix. DLL must be written. Third, you cannot call global variables from the DLL. If we declare a certain Global variables, such as: var s: byte. So this global variables can be used normally, but s cannot be used by calling programs, both s only as global variables to calling programs. But declaration in the calling program The variable can be passed to the DLL as a parameter. Four, the DLL called the call must exist.

This is very important. You must exist if you request the DLL file called when using a static call method and the function or process to be called. If you do not exist or specify the path and file name incorrect, the system will prompt "Outth" or "No * .dll file" or "No * .dll file" when running the primary program. Chapter 4 Dynamic call DLL TOP dynamic call DLL is relatively complicated in DLPHI, but very flexible. In order to fully explain the problem, this time we will give an example of a DLL called by C . First, compile the following DLL source program in C . #include extern "c" _declspec (dllexport) int WinAPI TestC (INT i) {return i;} Generate a DLL file after compiling, here we call the file as cpp.dll, only one of the DLL returns an integer type function Testc. For convenience, we still refer to the above call program, just replace the statements in the original Button1Click process with the following code. procedure TForm1.Button1Click (Sender: TObject); type TIntFunc = function (i: integer): integer; stdcall; var Th: Thandle; Tf: TIntFunc; Tp: TFarProc; begin Th: = LoadLibrary ( 'Cpp.dll'); {Loading DLL} if TH> 0 THEN TRY TP: = GetProcaddress (th, pchar ('testc')); if TP <> nil dam tf: = TintFunc (TP); Edit1.Text: = INTOSTR (TF (1 )); {Call TESTC function} END ELSE ShowMessage ('TestC function is not found "; Finally Freelibrary (TH); {Release DLL} end else showMessage (' cpp.dll did not find '); END; everyone has seen, This dynamic calling technology is very complicated, but as long as the parameters are modified, if the DLL name in LoadLibrary ('cpp.dll') is 'delphi.dll', the called DLL can be dynamically changed. 1. Define the type of function or process to be called. In the above code we defined a TintFunc type, which corresponds to the function TESTC we want to call. Do the same definition work in other calls. And also add the stdcall call parameters. Second, release the called DLL.

We use LoadLibrary dynamics to call a DLL, but remember to manually release the DLL with Freelibrary after use, otherwise the DLL will always use the memory until you exit Windows or shutdown. Now let's evaluate the advantages and disadvantages of two ways to call DLL. The static method is simple, easy to master and generally a little faster, but also more secure and reliable; however, the static method cannot flexibly loading the DLL required for running at runtime, but load the specified DLL until the main program starts running The DLL is released at the end of the program, and the method can be used only if the compiler and the system (such as Delphi) can be used. The dynamic method solves the deficiencies in the static method. It can easily access the functions and processes in the DLL, even newly added functions or processes in some old version DLLs; but the dynamic method is difficult to fully master, because of different Functions or processes must define a lot of complicated types and call methods. For beginners, the author recommends that you use a static method to use a dynamic call method after you are skilled. Chapter 5 uses DLL practical skills TOP one, write skills. 1. In order to ensure the correctness of the DLL, it can be written as part of the ordinary application. After the debug is correct, then from the main program, compile into a DLL. 2, in order to ensure the versatility of the DLL, the name of the visual control should be deducted in the DLL you have written, such as the Edit1 name in Edit1.Text; or custom type non-Windows definition, such as some record. 3, for easy debugging, each function and process should be as short as possible, and cooperate with specific detailed comments. 4, you should use TRY-Finally to handle possible errors and exceptions, pay attention to the SYSUTILS unit. 5, as little as possible to reduce the size of the DLL, in particular not to reference the visualization unit, such as the Dialogs unit. For example, in general, we can not reference the classes unit, which can reduce the compiled DLL to approximately 16KB. Second, call the skill. 1. When using a static method, you can rename the called function or process. In the DLL example written in the C mentioned earlier, if the extern "C" statement is removed, C will compile some strange function names. The original TESTC function will be named @ Testc $ S and so on, this Because C uses C Name Mangling technology. This function name is illegal in Delphi, we can solve this problem this: Rewriting the reference function is Function Testc (i: integer): integer; stdcall; external 'cpp.dll'; name '@ Testc $ s; Name The role is rename it. 2. Place the DLL we have written in the Windows Directory or under the WindowsSystem directory. Doing so can write only the name of the DLL in the external statement or the log path in the LoadLibrary statement. But doing this is somewhat improper, there is a large number of important system DLLs in these two directory. If your DLL is renowned, the consequences are unimaginable, and your programming technology does not reach the DLL written by yourself. Step in the system directory! Third, debugging skills. 1. We know that the DLL cannot run and single-step debugging when writing. There is a way, that is, set a host program in the Run | Parameters menu. Add a single step debugging, breakpoint observation, and running in the host program in the Host Application field of the local page.

转载请注明原文地址:https://www.9cbs.com/read-37482.html

New Post(0)