BPL use and the difference from DLL

xiaoxiao2021-03-05  24

BPL is DLL, this sentence is of course right. Simple example, of course, can be done, and you can do it very well, I have changed the offline browser of the left brother to this version: Multiple data connection methods, ADO, DOA, ODAC, IBX, Kao, each A connection corresponding to its specific database, is implemented in a separate BPL; the main program does not have any connection database, the main window is switched, as long as such a code: Class Function TfrmMain.selectveion (isadsettings: boolean): Boolean; var dmpkg, dmclassname: string; i: integer; usercanceled: boolean; begin result: = false; repeat dmpkg: = 'doadmdll.bpl'; // Simple version, directly prompt user Enter the name UserCanceled: = not InputQuery (Application.title, 'Modulename:', DMPKG);

DMClassName: = GetPackageDescription (PCHAR (DMPKG)); i: = POS ('[RicHexprdm]', DMClassName); try dm: = nil; Except end; // is the correct BPL, start loading if i> 0 THEN Begin // DataModule's class name DMClassName: = trim (COPY (DMClassName, i 12, max_path)); // Uninstall the current BPL unloadCurpkg; // Load the bpl fhaandle: = loadPackage (DMPKG) with loadpackage ; // Creating a DataModule instance DM: = TDMClass (DMClassName)). Create (Application); Result: = true; Else Application.MessageBox ('illegal DLL', '', MB_OK or MB_ICONEROR); Until Result Or userCanceled; END; then in Doadm.Pas: Initialization RegisterClass (TDOADM);

Finalization UnregisterClass (TDOADM); It is OK compiled into a BPL. This is really very simple to use BPL. Just use LoadPackage, each unit will directly use it directly Uses, INITIZATION and Finalizance will also do it, and then you will use it as a bpl. . This is the benefits of BPL, which can be easily divided into existing code into relatively independent modules.

However, it also has several fatal disadvantages. First it can't be like a DLL, compile it into the content or a few BPLs in a certain BPL, that is, as long as you reference another BPL, release When you have two BPLs, you must release it together. In addition, as long as a BPL references a unit, other BPLs cannot directly reference the unit compilation, but must reference a public BPL that contains this unit, otherwise you two BPLs It is impossible to load. With these two points, for large projects, it is very complicated, and the relationship between each module is difficult to handle. It is not like DLL, after compiling, each system will not say because of this DLL. This unit must be referenced, and the other DLL must reference the unit by other DLLs that reference this unit. Package in Delphi is a very powerful tool that can be used to play a very clear process of dividing the program. Because he built a description information, you can seamlessly integrate with the current code, you can protect any elements including classes, equivalent to the MFC Extension DLL in the VC. However, all the years have always introduced a method of static connection, which actually limits the use of Package because the static connection of Package has lost its flexibility, configurability, etc. As for access to the entry mode, it is really small, it is better to use DLL directly. How to dynamically load package, use the class, functions, variables, etc. It is very simple to wear, just do a agent package. Because in a Delphi program, each unit can only exist, otherwise conflicts. To dynamically load the package, you have to get information, and you can't directly use the Unit containing the information (otherwise conflict), the solution is to build an agent package as a bridge delivery information. Here is a simple example. The main program uses two packages. There is a simple form in the Demopak package; regPAK is a so-called agent package that acts as a registration information. The main program is static in REGPAK (set in Project Options), dynamically load Demopak (via loadPackage), while Demopak depends on Regpak (Requires), and register your own available class to the agent package registered to the agent package, here Registration information, you can make it easy to register other information

Unit Formreg;

Interface

Uses Classes, Sysutils, Forms, Contnrs

TYPE TFORMCLASS = Class of TForm;

Procedure registerformclass (const ANAMCLASS: TFORMCLASS); Procedure: String; Function FindformClass (const aname: string): TFormClass

IMPLEMentation

Var g_lstnames: tstringlist; g_lstforms: tclasslist;

Procedure RegisterformClass (const ANAME: TFORMCLAS); Begin G_lstnames.Add (Aname); g_lstforms.add (AFORMCLASS);

procedure UnregisterFormClass (const AName: string); var Index: Integer; begin Index: = g_lstNames.IndexOf (AName); if Index <> -1 then begin g_lstNames.Delete (Index); g_lstForms.Delete (Index); end; end ; function FindFormClass (const AName: string): TFormClass; var I: Integer; begin for I: = 0 to g_lstNames.Count - 1 do begin if g_lstNames [I] = AName then begin Result: = TFormClass (g_lstForms.Items [I ]); EXIT; End; End; Result: = nil; end;

Initialization g_lstnames: = tstringlist.create; g_lstforms: = tclasslist.create;

Finalization FreeAndnil (g_lstforms); FreeAndnil (g_lstnames);

End.

The above is the main code of Regpak, because examples, the code is very simple. The main thinking is to save registration information and provide query methods. Let us see the use in Demopak

UNIT ABOUTFORM;

Interface

Uses Windows, Messages, Sysutils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls;

TYPE TFRMABOUT = Class (TFORM) LBLABOUT: TLABEL; Private public end;

Var FRMABOUT: TFRMabout;

IMPLEMentation

Uses formreg;

{$ R * .dfm}

Initialization RegisterformClass (TfrmAbout.classname, Tfrmabout);

Finalization UnregisterFormClass (TfrmAbout.className); END.

Submit your own class information to the FormReg unit of REGPAK during initialization, because each package is automatically initialized when loading, and REGPAK is staticly referenced by the main program, and it is certainly initialized, so it is very simple. Finally, look at the use of the main program.

Uses formreg;

procedure TfrmMain.btnAboutClick (Sender: TObject); var hModule: THandle; begin hModule:. = LoadPackage ( 'DemoPak.bpl'); try with FindFormClass ( 'TfrmAbout') Create (nil) do try ShowModal; finally Free; end; Finally UnloadPackage (HMODULE); END;

Dynamically load the required package, query information of the required class, use it, and finally uninstall the package.

I have tried successfully like a DLL-like output, and it is successful in MDI. Post code, everyone is happy. I hope BBKXJY will take a score. The main reason is that the catalog of the BPL output defaults to / BP1. And I have not cared. bpl portion; ... type TUIPackageForm = class (TForm) DataSource1: TDataSource; DBNavigator1: TDBNavigator; DBGrid1: TDBGrid; procedure FormClose (Sender: TObject; var Action: TCloseAction); private {Private declarations} public {Public declarations} end; procedure ShowMDIChildForm (MainApp: TApplication); stdcall; exports ShowMDIChildForm; var UIPackageForm: TUIPackageForm; implementation {$ R * .DFM} procedure ShowMDIChildForm (MainApp: TApplication); stdcall; begin Application: = MainApp; UIPackageForm: = TUIPackageForm.Create (MainApp ); UiPackageform.show; end; procedure tuipackageform.formclose (Sender: Tobject; var Action: tclosection); begin action: = cafree; end; dynamic calling main section section. TYPE TSHOWMDIFORM = procedure (mainapp: tapplication); stdcall;

showmdiform: Tshowmdiform; begin UIConnect: = LoadPackage ( 'bpl'); showmdiform: = getprocaddress (UIConnect, 'ShowMDIChildForm'); if (@showmdiform <> nil) then showmdiform (application) else showmessage ( 'no prc'); end ;

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

New Post(0)