DLL encapsulation and calling object technology in Delphi (Liu Yi, with screenshots)

Source: Internet
Author: User

DLL encapsulation and calling object technology in Delphi
This article publishes the 3rd issue of Dr.dobb's software development, published in October 2003.
Liu Yi
Summary
DLL is one of the most widely used dynamic linking technologies, but the encapsulation and invocation of objects in DLLs are
The limitation of the dynamic binding mechanism makes the DLL have some technical difficulty in encapsulating the object, which leads to some Delphi
The sequencer mistakenly thinks that the DLL only supports encapsulated functions and does not support encapsulating objects This article focuses on the encapsulation and invocation of DLLs in the
The principles and ideas of the image and the combination of examples give a number of different implementation methods
Keyword dynamic link library DLL Object interface virtual method Dynamic binding class reference Object oriented
1 Physical package and dynamic link
The physical encapsulation means that the program is encapsulated into a number of separate physical components by dynamic chaining between the parts
The function of the system and the individual physical components can be maintained and compiled independently of the other parts to
Understanding physical encapsulation First of all, make sure that static and dynamic links
In Delphi, if each module of the program is stored in a separate unit file and is uses
Call each other this is a typical static link then the various static subroutines are compiled after the connector from Delphi
A compiled unit or a static library takes out subroutine compilation code and adds the final EXE package to the execution file
All code that encloses the program and its owning unit is apparently statically linked to a unit or module that ultimately has a separate physical shape
Executable file exists in addition to the unit file you have written Delphi also automatically uses some of the preset units
These are static links such as Windows Messages
Static linking does not enable physical cutting and encapsulation and once one of the cells or modules changes all other
The unit or module has to be recompiled and connected with it.
BPL package DLLs for physical cutting and encapsulation dynamic link libraries or COM + components are dynamic links
The form in a dynamic link situation in which the connector uses only the information in the subroutine external declaration is generated in the execution file
Some data tables when Windows loads the execution file into memory, it first loads all the required DLLs and then
The program will not start the internal table in the loading process for Windows with functions in memory address filler
Whenever a program calls an external function, it uses the internal data table directly to the DLL code it is currently
Load is invoked in the program's address space note that the pattern does not involve two different application DLLs
has become part of the application and loaded in the same address space all parameters are passed on the stack
As with any other function call here, we're not going to talk about DLL compilation, because first we want to focus on
DLL encapsulation and calling object technology in Delphi
2 encapsulating objects with DLLs
DLL Dynamic link library is no longer what new technology readers are now
To find the chapters on DLL programming in an outdated Delphi book in a bookstore, but these are books that involve DLL programming.
Is almost always talking about using DLLs to encapsulate functions. Actually a lot of programmers are also using DLLs to encapsulate functions
Or a process-oriented module a collection of functions and here I just want to discuss how to encapsulate objects with DLLs
This may be a DLL experience that the reader has never had, but this is an important part of this book, which is completely centered around object-oriented programming.
One of the parts maybe you can find some different practical tricks.
See the current information about DLLs in mind for a lot of here I omitted the basic knowledge of DLLs and write
Method assumes that the reader already has a certain foundation for DLL programming if you do not have such basic recommendations see
My book Delphi6 Enterprise-Class solution and application Profiling DLL programming Technology Section P271
In general, using DLLs to encapsulate objects primarily has the following benefits
?? Save memory multiple programs can use the same DLL when the DLL only needs to be loaded once and can only
Destroy when load is not used
?? Reuse of program code this is to say that objects encapsulated with DLLs can be reused or even let
The same program language call
?? Modular assembly of the program to facilitate team development and maintenance and update convenience
However, DLL in the packaging of the object has a certain degree of technical difficulty this information is very little even some programmers mistakenly
Encapsulating objects is not supported for DLLs that only support encapsulation functions
Through research we find that the main limitation of DLLs on encapsulated objects is
?? The application that invokes the DLL can only use the method of dynamic binding of objects in the DLL
?? An instance of a DLL wrapper object can only be created in a DLL
?? Both the encapsulated object and the method called are required to sound in both the DLL and the application calling the DLL.
Ming
Let me start with a simple example of how to use a DLL to encapsulate an object and invoke it in an application.
Object and then discuss the relevant technical details
31 Simple Examples
The reader must remember that we demonstrated in the previous chapters that the vehicle's inheritance and composition relationships This program consists of a logic sheet
Meta Demo and Interface Unit Frmdemo we now use DLLs to encapsulate all the objects of the demo unit and
In the Frmdemo cell implementation call Reader can use this specific example to learn how to encapsulate an object using a DLL
Open the project file as shown in Project manager OBJDEMO.DPR 1 Mouse
Right-click ProjectGroup1 and select Add New Project from the pop-up menu ... The menu item now pops up with 2
Show the New Items dialog box to select the DLL Wizard Delphi DLL wizards will create a DLL project I
Rename the project to Demosvr and save it in the same directory as the project group


Figure 1 Mouse Right-click ProjectGroup1 in the pop-up menu, select Add New Project ... Menu items


Figure 2 Selecting the DLL Wizard in the New Items dialog box
Modify the code in DEMOSVR as shown in example program 1
Sample Program 1 dynamic-link library demosvr main program
Library demosvr;
{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
Sharemem,
Sysutils,
Classes,
Demo in ' Demo.pas ';
{$R *.res}
function Carobj:tcar;
Begin
Result:=tcar.create;
End
function bicycleobj:tbicycle;
Begin
Result:=tbicycle.create;
End
Exports
Carobj,
Bicycleobj;
End.
This shows that an instance of the DLL wrapper object is created in the DLL with the carobj and Bicycleobj functions.
and output a reference to the car object and the bicycle object so that the DEMOSVR dynamic link library can be carobj and
The Bicycleobj function outputs the car object and the bicycle object, but the car object and the bicycle object are in the Demo.pas
Declared and implemented in the file, so here's uses Demo.pas.
In order to be able to use Demo.pas to drag the Demo.pas file directly from the Objdemo project in the project manager
Put it in the Demosvr project, as shown in 3


Figure 3 Drag and drop the Demo.pas file from the Objdemo project into the DEMOSVR project
Open Demo.pas Modify the tbicycle and Tcar declarations as follows
Tbicycle = Class (Tvehicle)
Public
constructor create;
destructor Destory;
Procedure ride;virtual;
End
TCar = Class (Tvehicle)
Protected
Fengine:tengine;
Public
constructor create;
destructor Destory;
Procedure drive;virtual;
End
Notice here that I've changed the object method that needs to be called in the application ride and drive to a virtual method, apparently.
This is not done to allow derived classes of tbicycle and Tcar to overwrite the ride and drive methods because the connection is compiled
Application, the compiler cannot know or know how to implement the method of the object in the DLL, which means
For applications to use dynamic binding late binding technology, the application that invokes the DLL can only
The method of dynamic binding of objects in DLLs before we talked about the dynamic binding technique of virtual method is to put the virtual method into
The VMT in the virtual method table VMT is a piece of memory that contains the object method pointer through the VMT calling program can
To get a pointer to the virtual method if we don't declare ride and drive as virtual VMT there will be no such parties
Method of the entry pointer so that the calling program will not be able to get the entry pointer for this method
Next go back to the Frmdemo unit in the application that invokes the DLL to declare the object that needs to be called and its
The called method is declared as an abstract method in addition to declaring ride and drive as virtual methods because
Frmdemo units do not provide implementations of the ride and drive methods do not declare them as abstract methods and compile without
The complete code for the application Frmdemo unit is shown in example program 2
Example program 2 calling the application of a DLL object
Unit Frmdemo;
Interface
Uses
Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms,
Dialogs, Stdctrls;
Type
---Here declares the method of the object in the DLL that needs to be used---
Tvehicle = Class (TObject);
TCar = Class (Tvehicle)
Public
Procedure Drive;virtual;abstract;
End
Tbicycle = Class (Tvehicle)
Public
Procedure Ride;virtual;abstract;
End
//----------------------------
TForm1 = Class (Tform)
Button1:tbutton;
Button2:tbutton;
Procedure Button2click (Sender:tobject);
Procedure Button1Click (Sender:tobject);
Private
{Private declarations}
Public
{Public declarations}
End
Var
Form1:tform1;
---here to import DLL files and their functions---
function Carobj:tcar; external ' DemoSvr.dll ';
function bicycleobj:tbicycle; external ' DemoSvr.dll ';
Implementation
{$R *.DFM}
Procedure Tform1.button2click (Sender:tobject);
var Mycar:tcar;
Begin
Mycar:=carobj;
If Mycar=nil then exit;
Try
mycar.drive;
Finally
Mycar.free;
End
End
Procedure Tform1.button1click (Sender:tobject);
var bicycle:tbicycle;
Begin
Bicycle:=bicycleobj;
Try
Bicycle.ride;
Finally
Bicycle.free;
End
End
End.
Finally select Build all Projects menu item compile and connect all of the items shown in 4 we'll have to
To the required application executables as well as DLL run tests can see this program implemented and originally a
Kind of function
But I'm not too satisfied with the implementation of this DLL wrapper object because it needs to be declared in both DLLs and applications.
Encapsulating objects also use good virtual and abstract qualifiers, which can easily create an illusion of reading comprehension.
If an object changes, you need to modify the object declaration on both sides to keep the synchronization slightly wrong
About this Steve Teixeira in the Delphi6 Developer Guide for Mechanical Industry Press 2003 publishing related content
Refer to the book in page 209 for a method of using a header file and by adding a compile instruction to control the DLL and
Use the program to read different header file contents This method, although you can only modify the header file to maintain the declaration of the same
Step but compile directives and header files make reading programs more difficult
Here I have a better way for readers to share this is how the interface is used
4 using Delphi interface to implement dynamic binding of objects in DLLs
We have previously analyzed that the application invoking the DLL can only use the method of dynamic binding of objects in the DLL to understand
This is the key to implementing DLL encapsulation and using objects so Delphi interface technology provides us with an optimal
Choose

Figure 4 Selecting the Build All Projects menu item compiling and connecting all items
For this purpose we create an interface unit Idemo declares the ICAR and Ibicycle interface methods respectively are
The complete code for the drive and ride used by the application is shown in example program 3
Code for Sample Program 3 interface Unit Idemo
Unit IDemo;
Interface
Type
ICar = Interface (iinterface)
[' {ed52e264-6683-11d7-b847-001060806215} ']
Procedure Drive;
End
Ibicycle = Interface (iinterface)
[' {ed52e264-6683-11d7-b847-001060806216} ']
Procedure Ride;
End
Implementation
End.
Note that there is no and no implementation of the interface unit Idemo it is used by both the application and the DLL
Use this when you need to modify an object method called by an application whenever the interface unit is in one place
Modify to avoid possible declaration inconsistency errors
The use of interfaces also brings additional benefits first without using the virtual and abstract qualifiers to modify the object method sound
To avoid the illusion of program reading secondly, using the interface instance counter to automatically manage the lifetime of the object avoids
Programmer forgets memory leaks caused by destroying objects
In order to use the interface I made the following modifications to the Type Declarations section of the demo unit to Tbicycle and Tcar
Class is able to implement an interface method it is gratifying to note that the unit only needs to modify the declaration part and the program implementation part of the fundamental
No need to make any changes
Unit Demo;
Interface
Uses
Sysutils, Windows, Messages, Classes, Dialogs,idemo;
Type
Tvehicle = Class (Tinterfacedobject)
Protected
fcolor:string;
fmake:string;
Ftopspeed:integer;
Fwheel:twheel;
Fwheels:tlist;
Procedure slowdown;
Procedure SpeedUp;
Procedure Start;
Procedure Stop;
End
Tbicycle = Class (Tvehicle,ibicycle)
Public
constructor create;
destructor Destory;
Procedure ride;
End
TCar = Class (Tvehicle,icar)
Protected
Fengine:tengine;
Public
constructor create;
destructor Destory;
Procedure Drive;
End
Finally, check the project manager to ensure that the Idemo unit is added in both the application project and the DLL project
5 is shown

Figure 5 Ensure that the interface unit is added in both the application project and the DLL project Idemo
Sample program 4 application that uses interface technology to invoke DLL objects
Unit Frmdemo;
Interface
Uses
Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms,
Dialogs, Stdctrls, idemo;//here use IDemo Unit
Type
TForm1 = Class (Tform)
Button1:tbutton;
Button2:tbutton;
Procedure Button2click (Sender:tobject);
Procedure Button1Click (Sender:tobject);
Private
{Private declarations}
Public
{Public declarations}
End
Var
Form1:tform1;
function Carobj:icar; external ' DemoSvr.dll ';
function bicycleobj:ibicycle; external ' DemoSvr.dll ';
Implementation
{$R *.DFM}
Procedure Tform1.button2click (Sender:tobject);
var Mycar:icar;
Begin
Mycar:=carobj;
mycar.drive;
Mycar:=nil;
End
Procedure Tform1.button1click (Sender:tobject);
var bicycle:ibicycle;
Begin
Bicycle:=bicycleobj;
Bicycle.ride;
Bicycle:=nil;
End
End.
Not many changes in the example program 4 here Use the Idemo unit without additional declaration implementations
The interface method in the DLL is called partially through the interface, or it can be said that the object method runs the sample program 4 and runs the
Example program 2 implements exactly the same function
5 using abstract classes to implement dynamic binding of objects in a DLL
Since the encapsulated and called objects in the DLL are constrained by the dynamic binding mechanism of the object, in addition to using the Delphi connection
Port Technology We can also consider using abstract classes to implement dynamic binding mechanisms for objects in DLLs

Figure 6 shows an object-oriented design of a sample program based on a database application I design the interface part as a
The form of a thin client this is an executable file for user interaction Distributabel2.exe it encapsulates the appearance
Class Tfrmusers I put the business section including the data module designed to serve the server which is a dynamic chain
Library file UserSvr.dll It encapsulates the business class Tusermaint and the database access class TUSERDM this design
Embodies the idea of interface and business separation

Figure 6 Design of the physical separation of interfaces and services
Since the original logic-independent classes and code are stored in different cell files, we can easily re-classify them
To a different project 7 shows


Figure 7 Re-dividing the logically separate unit files into different projects
A thin client is actually an empty shell that only provides an interactive interface its appearance class tfrmusers to
Tusermaint Instance Object Request service This object is encapsulated in a DLL before I've talked about how to use DLLs to seal
In addition to the two methods described earlier here I would like to introduce the third method that uses the abstract class to do the interface
Method
Because the application that calls the DLL can only use the dynamic binding method of objects in the DLL, we may wish to specifically design
An abstract class Tiusermaint as an interface for providing object methods has a supply path in the abstract class Tiusermaint
The object method used by the order but they are all virtual abstract methods The purpose is to support dynamic binding without providing implementation
I put the new tiusermaint in the abstract class interface unit Uiusermaint.pas file whose source code such as example
As shown in program 5, this unit will be included as an interface file in the USERSVR and Distributable2 projects respectively 7
is shown
Sample program 5 abstract class interface Unit Uiusermaint code
Unit uiusermaint;
Interface
Uses
Classes;
Type
Tiusermaint = Class (TObject)
Public
function getdeplist:tstrings;virtual;abstract;
function Getuserlist (strname:string): olevariant;virtual;abstract;
Procedure Updateuserdata (userdata:olevariant; out Errcount:integer);
Virtual;abstract;
Constructor Create;virtual;abstract;
End
Tiusermaintclass=class of Tiusermaint;
Implementation
No implementation code
End.
The Tiusermaintclass type is also defined in the example program 5, which is the class reference of the Tiusermaint.
is necessary to pass the implementation class from the DLL to the calling application
The generic abstract class only defines interfaces it consists of virtual abstract methods without actual data in order to implement abstract classes
Tiusermaint Abstract method The original Tusermaint class needs to inherit the Tiusermaint class and overwrite all of its
The new Tusermaint class declaration of the virtual abstract method is as follows
Tusermaint = Class (Tiusermaint)
Private
USERDM:TUSERDM;
Public
function Getdeplist:tstrings;override;
function Getuserlist (strname:string): olevariant;override;
Procedure Updateuserdata (userdata:olevariant; out Errcount:integer);
Override
Constructor Create;override;
destructor Destroy;override;
End
But in fact, the original implementation of the Tusermaint class does not need to be changed, so our workload is small
Sample program 6 is the source code for the dynamic link library UserSvr.dll Here I used the tobjusers function.
The number returns a class reference of type Tiusermaintclass instead of an object reference so that in the application you can make
Use this code to create a DLL-encapsulated object
Objusers:=tobjusers.create;
But that doesn't mean tobjusers is a class remember here tobjusers is a DLL output function it
The return type is a class reference type
Sample program 6 source code for dynamic link library UserSvr.dll
Library usersvr;
Uses
Sharemem,
Sysutils,
Classes,
Uusermaint in ' Uusermaint.pas ',
Udmuser in ' Udmuser.pas ' {userdm:tdatamodule},
Uiusermaint in ' Uiusermaint.pas ';
{$R *.res}
function Tobjusers:tiusermaintclass;
Begin
Result:=tusermaint;
End
Exports
Tobjusers;
Begin
End.
The attentive reader may have discovered that since the return type of the Tobjusers function is Tiusermaintclass
Tiusermaintclass is declared in the example program 5 as:
Tiusermaintclass=class of Tiusermaint;
So will result:=tusermaint be wrong?
We have declared an object of type Tiusermaint in our application Objusers by passing class citation
The objusers:= tusermaint.create function is implemented with the Objusers:=tobjusers.create statement here
It implies that the process of transformation of Tusermaint to Tiusermaint is of course Tiusermaint as an abstract class itself without
To create your own instance directly, so you have to transform it. Additionally, in the derived class of Tiusermaint, you can follow the
The implementation of the change method does not affect the interface of the method this means that you later by further modifying the DLL seal
To upgrade the DLL without having to re-modify and compile the application because Tiusermaint as an abstract
The method interface provided by the class has not changed
Sample program 7 is the source code of the interface unit after the application implementation interface and the physical separation of the business here to note
What time does it mean
?? In the interface section to uses the abstract class interface Unit Uiusermaint
?? Objusers declared as Tiusermaint type
?? declaring DLL functions function Tobjusers:tiusermaintclass; External ' UserSvr.dll ';
In addition, there is little need for other changes to evolve from the logical separation of the interface and the business to the boundary
Physical separation of polygons and business is not really as difficult as it might seem.
Sample program 7 physical separation of the interface Unit code
Unit ufrmusers;
Interface
Uses
Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Dbclient, Stdctrls, Dbctrls, Grids, Dbgrids, Mask, Extctrls,
Buttons,uiusermaint;
Type
Tfrmusers = Class (Tform)
Btnexit:tbutton;
Btnqrybyname:tspeedbutton;
Label1:tlabel;
Label2:tlabel;
Label3:tlabel;
Label5:tlabel;
Label6:tlabel;
Label7:tlabel;
Edtqrybyname:tlabelededit;
Dbedit1:tdbedit;
Dbedit2:tdbedit;
Dbedit3:tdbedit;
Dbedit4:tdbedit;
Dbgrid1:tdbgrid;
Dbcbsex:tdbcombobox;
Dbcbdep:tdbcombobox;
Datasource1:tdatasource;
Cdsusermaint:tclientdataset;
Cdsusermaintid:twidestringfield;
Cdsusermaintname:twidestringfield;
Cdsusermaintsex:twidestringfield;
Cdsusermaintjob:twidestringfield;
Cdsusermainttel:twidestringfield;
Cdsusermaintcall:twidestringfield;
Cdsusermaintdep:twidestringfield;
Cdsusermaintgroup_id:twidestringfield;
Cdsusermaintpassword:twidestringfield;
BTNUPDATE:TBITBTN;
Procedure Btnupdateclick (Sender:tobject);
Procedure Btnqrybynameclick (Sender:tobject);
Procedure Formcreate (Sender:tobject);
Procedure Btnexitclick (Sender:tobject);
Procedure Formdestroy (Sender:tobject);
Private
Objusers:tiusermaint;
Public
{Public declarations}
End
Var
Frmusers:tfrmusers;
Const
M_title= ' Operation Tip ';//title of all prompt dialogs
Implementation
{$R *.DFM}
function Tobjusers:tiusermaintclass;
External ' UserSvr.dll ';
Procedure Tfrmusers.btnupdateclick (Sender:tobject);
Var
Nerr:integer;
Begin
If Cdsusermaint.state=dsedit then cdsusermaint.post;
if (Cdsusermaint.changecount > 0) Then
Begin
Objusers.updateuserdata (Cdsusermaint.delta,nerr);
If Nerr>0 Then
Application. MessageBox (' update failed ', m_title,mb_iconwarning)
Else
Begin
Application. MessageBox (' Update successful ', m_title,mb_iconinformation);
Btnqrybynameclick (nil);
End
End

Http://www.cnblogs.com/kfarvid/archive/2010/06/24/1764441.html

DLL encapsulation and calling object technology in Delphi (Liu Yi, available)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.