Delphi's high-grade DLL writing and call (Suurum) You can quickly complete the general DLL write and calling applications quickly based on the DLL information provided by Delphi. The subject matter described herein is how to write and call the DLL capable of passing various parameters (including object instances). For example, the calling program is passed to a DLL an Adoconnection object example as a parameter, and the function and procedure call in the DLL pass the database through the object instance. Need to clear some basic concepts. For the DLL, you need to include an Exports clause in the main program to provide a call interface to the outside, and the clause is a series of functions or procedures names. For call squares (call DLL applications or other DLLs), you need to perform an external statement before calling, that is, the declaration of the external reserved word indication. These are the elements that the DLL must be written and the DLL must have. In addition, you need to understand the contents of the invocation protocol in Object Pascal. In Object Pascal, there are the following five call protocols for processes and functions: indicating whether the word parameter transmission sequence parameter clerutor parameter uses register register from left to right-adjusted routine, PASCAL from left to right modulverted CDECL Right to Left Model No STDCALL Self-Left Archeted No SaFECALL Since the right direction left is adjusted by the indication of the way is the reserved word after the declaration function or the process is attached to the routine title, the default is register That is, the only parameter transfer method using the CPU register is also the fastest way to pass the speed; the PasCal: The call protocol is only compatible backwards, ie, is compatible with the old version; CDECL: multi-use routine written in C and C language Also used for routines that need to be cleared by the caller; stdcall: and SaFECALL are primarily used to call the Windows API function; where SaFECALL is also used for dual interfaces. In this example, the call protocol CDECL will be used because the database connection used is passed by the calling party, and needs to be closed and destroyed by the calling party. Below is the DLL full source program and the caller full source program.
Including the following four files: project1.dpr {calling program} unit1.pas {call program unit} process2.dpr {dll} Unit2.PAS {DLL unit} {---------- DLL main program Project2.dpr ----------} library project2; usessysutils, classes, unit2 in 'unit2.pas' {form1}; {$ r * .res} {below the following statement is used to call the DLL Program provides call interface} exportsDotest; {process comes from unit unit2} beginend. {----------- Unit2.Pas in DLL --------} Unit unit2; InterfaceUseswindows, Messages , SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Db, ADODB, StdCtrls, Menus; typeTForm1 = class (TForm) ADOConnection1: TADOConnection; {native database connectivity} Memo1: TMemo; {for displaying information} privatepublicend; {the Outback provides} Procedure Dotest (H: Thandle; {get the caller's handle} Aconn: tadoconnection; {get the caller's database connection} S: String; {Get some text information} n: integer; {Get some values Information} CDECL; {Specify Call Protocol} Implementation {$ R * .dfm} Procedure Dotest (H: Thandle; Aconn: Tadoconnection; s: String; N: Integer; beginApplication.handle: = H; {将 Handle assignments The function of the called {The role of the above statement is the same, the DLL handle and the caller's handle are not in the taskbar. } {Each appears a task title.
} with tform1.create (Application) DO try {Create Form} Memo1.Lines.Append ('Successful Call'); {Show a line of information} adoconnection1: = Aconn; {Get database connection instance} Memo1.Lines.Append Adoconnection1.connectionstring '-' S '-' INTOSTR (N)); {According to the resulting parameter display another row information} showModal; {mode displays the form} finallyfree; {Test window} END; End; end. {---------- Call project1.dpr, very ordinary engineering file ----------} Program Project1; Usessforms, Unit1 in 'unit1.pas' { Form1}; {$ r * .res} BeginApplication.initialize; Application.createform (TFORM1, FORM1); Application.Run; end. {---------- Call Unit Unit1.pas ---- ------} unit Unit1; interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Db, ADODB; typeTForm1 = class (TForm) Button1: TButton; {} ADOConnection1 Press to call : Tadoconnection; {Local database connection, pass to DLL} procedure button1click (sender: TOBJECT); {call DLL} privatepublicnd; varform1: tform1; importm ENTATION {$ r * .dfm} {External declaration must be consistent with the parameter list in the DLL, otherwise error} procedure dotest (H: Thandle; {Pass handle} Aconn: tadoconnection; {delivery database connection} s: string; {Pass text information} n: integer; {Pass numerical information} CDECL; {Specify call protocol} external 'project2.dll'; {Specify process source} {Call process} procedure TFORM1.BUTTON1CLICK (Sender: TOBJECT); begindotest Application.Handle, Adoconnection1, 'Call OK', 256); End; End.
The above can pass an adoconnection connection to see the following passing a chart, but passing an adotable is not DLL unit unit1; InterfaceUses Windows, Messages, Sysutils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, TeeProcs, TeEngine, Chart, StdCtrls, Buttons, DB, Grids, DBGrids, ADODB; type Tfun = ^ Tchart; TfunAdotable = ^ Tadotable; TForm1 = class (TForm) Chart1: TChart; BitBtn1: TBitBtn; ADOConnection1: TADOConnection; ADOTable1: TADOTable ; DBGrid1: TDBGrid; DataSource1: TDataSource; procedure BitBtn1Click (Sender: TObject); private {Private declarations} public {public declarations} end; procedure performdll (ahandle: thandle; afun: tfun; funAdotable: TfunAdotable); stdcall; external 'dll .dll 'name' performdll '; var Form1: TForm1; implementation {$ R * .dfm} procedure TForm1.BitBtn1Click (Sender: TObject); var myfun: Tfun; funAdotable: TfunAdotable; begin myfun: = @ chart1; performdll (handle , myfun, funadotable; end; End.exe call procedure as follows: Unit Dllmain; InterfaceUses Windows, Messages, Sysutils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, TeeProcs, TeEngine, Chart, DB, ADODB, DBCtrls; type Tfun = ^ Tchart; TfunAdotable = ^ tadotable; TForm1 = class (TForm) Button1: TButton; DBNavigator1 : TDBNavigator; DataSource1: TDataSource; Button2: TButton; procedure Button1Click (Sender: TObject); procedure Button2Click (Sender: TObject); private {Private declarations} public {public declarations} end; function performdll (ahandle: thandle; afun: tfun; Funadotable: TFunadotable: Integer; stdcall; var form1: tform1; fun: tfun; myfunadotable: tfunadotable; impLementation {$ r * .dfm} Function PerformDll (AHANDLE: THANDLE; AFUN: TFUN;