In order to allow people to quickly understand static calls, dynamic calls, now do a function encapsulated in a DLL, and then in the application form inside call this function, this function handles two number of the and. To speak in code and pictures: The code is as follows Library Project1; {Important Note about DLL memory Management:sharemem must is the First unit in your library ' s USES clause and your project ' s (select Project-view Source) USES clause If your DLL exports any procedures or Functions that pass strings as parameters or function results. This Applies to all strings passed to and from your dll--even those is nested in records and classes. SHAREMEM is the interface unit to The BORLNDMM. DLL shared Memory manager, which must be deployed along With your DLL. To avoid using BORLNDMM. DLL, pass string information Using PChar or shortstring parameters. } Uses Sysutils, Classes; function INCC (a,b:integer): integer; stdcall; The real code begins; Begin Result: =a+b; End {$R *.res} Exports//Allow invocation; INCC;
End.
A Project1.dll DLL file will be generated under the folder after compiling by CTRL+F9. Below, we begin to invoke the functions in this DLL in two ways: static and dynamic calls. One: Static call Create a new application form to add a two text box to it, and name edt1,edt2 to speak in code. Unit Unit1; Interface Uses Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls; Type TForm1 = Class (Tform) Btn1:tbutton; Edt1:tedit; Edt2:tedit; Procedure Btn1click (Sender:tobject); Private {Private declarations} Public {Public declarations} End Var Form1:tform1; Implementation function INCC (A,b:integer): Integer;stdcall; External ' Project1.dll '; Load this dynamic library.
{$R *.DFM} Procedure Tform1.btn1click (Sender:tobject); Var Aa:integer; Begin AA:=INCC (Strtoint (edt1. Text), Strtoint (EDT2. Text));//Start Calling ShowMessage (IntToStr (AA));//Popup results. End End. Two: Compared to static calls, dynamic calls occupy a small point of resources, gee, the specific benefits I will not say, now see how concrete can be achieved, the same in the establishment of a static call and the form. Then speak in code. Unit Unit11; Interface Uses Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls; Type TForm1 = Class (Tform) Edt1:tedit; Edt2:tedit; Btn1:tbutton; Procedure Btn1click (Sender:tobject); Private {Private declarations} Public {Public declarations} End Var Form1:tform1; Implementation {$R *.DFM} Type Tmyfun = function (a,b:integer): integer; stdcall;//defines a function type, note that the parameters of the procedure type should be consistent with the parameters of the method used in the DLL. Procedure Tform1.btn1click (Sender:tobject); Var Myhandle:thandle; Fpointer:pointer; Myfun:tmyfun; Begin Myhandle:=loadlibrary (' C:\Documents and settings\administrator\ desktop \ New Folder \project1.dll ');//Load this DLL If Myhandle >0 then//is successfully loaded, it executes. Try Fpointer: =getprocaddress (Myhandle,pchar (' INCC ')); Take the address of the function. If Fpointer <>nil then//If the function exists, call Begin Myfun: = Tmyfun (Fpointer); ShowMessage (IntToStr (Myfun (Strtoint) (EDT1. Text), Strtoint (EDT2. Text)));//Popup calculates the result. End Except FreeLibrary (Myhandle); End End End. Statically invoking DLLs in Delphi
It is easier to call a DLL than to write a DLL. The first is to introduce the static call method, the dynamic call method will be introduced later, and a comparison of the two methods. Again, let's start with an example of a static call. 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}
Our code below is the code we actually write.
function Testdll (I:integer): Integer;stdcall; External ' Delphi.dll ';
Procedure Tform1.button1click (Sender:tobject); Begin Edit1.text:=inttostr (Testdll (1)); End
End. First, call parameters with StdCall As mentioned earlier, you should also use the stdcall parameter when referencing functions and procedures in a DLL, for the same reason as mentioned earlier. Second, specify the path and name of the called DLL file with the external statement As you can see, we specify the name of the DLL file to invoke in the external statement. There is no write path because the DLL file is in the same directory as the main program that called it. If the DLL file is in C: \, then we can write the above reference statement as external ' C:\Delphi.dll '. Note the file suffix. dll must be written on. Three, cannot call global variables from DLL If we declare a global variable in the DLL, such as Var s:byte. In this case, the s global variable in the DLL can be used normally, but s cannot be used by the calling program, and S cannot be passed as a global variable to the calling program. However, variables declared in the calling program can be passed as arguments to the DLL. IV, the called DLL must exist This is important when using a static call method requires that the DLL file being called and the function or procedure to be called must exist. If there is no or the specified path and file name is incorrect, a run-time error such as "Error launching Program" or "*.dll File not found" is prompted when you run the main program. Dynamically invoking DLLs in Delphi Dynamic call DLLs are relatively complex, but very flexible. To give a full explanation of the problem, let's take an example of invoking a DLL written by C + +. The following DLL source program is compiled in C + + first.
#include
extern "C" _declspec (dllexport) int WINAPI TESTC (int i) { return i; }
compiled into a DLL file, where we call the file Cpp.dll, there is only one function in the DLL that returns an integer type TESTC. To make it easier to explain, we still refer to the above calling program, just replace the statement 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 '); {load dll} if th>0 then try tp:=getprocaddress (Th,pchar (' TESTC ')); If tp< >nil then begin Tf:=tintfunc (Tp); Edit1.text:=inttostr (Tf (1)); {Call TESTC function} end else showmessage (' testc function not found '); finally FreeLibrary (TH); {release dll} end else ShowMessage (' Cpp.dll not Found '); End; One, defines the type of function or procedure to invoke In the above code we define a Tintfunc type, which corresponds to the function we are going to invoke TESTC. The same definition work should be done in other invocation cases. And also add the stdcall call parameter. Second, release the called DLL We call a DLL dynamically with LoadLibrary, Remember, however, that you must manually release the DLL with FreeLibrary after you have finished using it, or the DLL will take up memory until you exit Windows or shut down. Now let's evaluate the pros and cons of the two methods of invoking DLLs. Static methods are simple, easy to master and generally a little faster and more secure, but static methods do not have the flexibility to unload the required DLLs at run time, but instead load the specified DLLs when the main program starts running and then release the DLL when the program ends. In addition, the method can be used only by compilers and linker-based systems such as Delphi. The dynamic method solves the shortcomings in the static method, it can easily access the functions and procedures in the DLL, even some new functions or procedures in the old version dll, but the dynamic method is difficult to grasp completely, because different functions or procedures need to define many complex types and calling methods. For beginners, I recommend that you use static methods, and then use the dynamic call method until you are proficient. useful tips for using DLLs top
first, writing skills 1, in order to ensure the correctness of the DLL, can be written into a common part of the application, debugging and error after the separation from the main program, compiled into a DLL.
2, in order to ensure the universality of the DLL, should be in their own DLL to prevent the name of the visual control, such as: Edit1.text in the Edit1 name, or custom non-Windows defined type, such as a record.
3, for easy debugging, each function and process should be as short as possible, and with specific detailed comments.
4. Use try-finally to handle possible errors and anomalies, and note that you should refer to the Sysutils unit.
5. Use as few references as possible to reduce the size of the DLL, especially if you do not reference a visualization unit, such as a dialogs unit. In general, for example, we can not reference the classes unit, which reduces the compiled DLL by approximately 16Kb.
second, the call technique 1. When using a static method, you can rename the called function or procedure. In the previously mentioned DLL example written in C + +, if you remove the extern "C" statement, C + + will compile some strange function names, the original TESTC function will be named @testc$s and so on ridiculous strange name, this is because C + + uses the C + + name mangling technology. This function name is illegal in Delphi, so we can solve this problem: Overwrite the reference function as
function TESTC (I:integer): Integer;stdcall; External ' Cpp.dll '; name ' @TestC $s '; Where name is the function of renaming.
2. You can put the DLLs we write into the Windows directory or the Windows\System directory. This allows you to write only the name of the DLL in the external statement or in the LoadLibrary statement without writing the path. But this is a bit inappropriate, these two directories have a large number of important system DLLs, if you make a DLL with their name, the consequences of this is unthinkable, and your programming technology is not enough to put your own DLL into the system directory of the point!
Three, debugging skills 1, we know that DLLs are not to be run and single-step debugging when writing. One way to do this is to set up a host program in the Run|parameters menu. The name of the host program is added to the host application column on the local page for single-step debugging, breakpoint observation, and operation.
2. Add the version information of the DLL. The prologue mentions that version information is important for DLLs, and if the version information is included, the size of the DLL increases by 2KB. It is worthwhile to add such a little space. Unfortunately, if we use the Project|options menu in the version option is not possible, this is not mentioned in the Delphi help file, after the author found that as long as the addition of a line of code on it. The following example:
Library Delphi;
Uses Sysutils, Classes;
{$R *. RES} Note that this line of code must be added to this position
function Testdll (I:integer): Integer;stdcall; Begin Result:=i; End
Exports Testdll;
Begin End.
3, in order to avoid the same name as other DLLs, in the DLL to write their own names when it is best to use a combination of character numbers and underscores. such as: Jl_try16.dll.
4, if you originally in Delphi 1 or Delphi 2 has compiled some DLLs, you originally compiled DLL is 16-bit. You can get 32-bit DLLs as long as the source code is recompiled in the new Delphi 3 or Delphi 4 environment.
[PostScript]: In addition to the DLL described above the most commonly used methods, DLLs can also be used to do the resources of the carrier. For example, changing an icon in Windows is a resource in a DLL that is used. In addition, mastering the design techniques of DLLs has many benefits for using more advanced OLE, COM, and ActiveX programming. |