Bahamut
http://www.cnpack.org
(Please specify and remain intact)
The package mentioned earlier is actually a logical package. Logical encapsulation is the encapsulation of a particular logical function module, which can be a class or a package, and they all have their own logical boundaries. Another way of encapsulation, we call it physical packaging: physical encapsulation is actually a physical collection of implementation code, he can be bpl,dll,com+ and other forms of expression.
In the logical package, the object's passing, data sharing and invocation are much simpler, as long as we can directly access the properties or methods published by the public and published in the class by referencing the cells defined by the class, and at compile time, The compiler will package all referenced units in the project into the EXE. The logical package ultimately exists as a separate physical file. Although simple, it is not possible to physically cut, and once one of the cells or snippets changes, other cells or code snippets need to be recompiled and connected.
In the physical package, the transfer of objects, data sharing and invocation is much more complex, because at compile time, EXE and DLL or BPL is two or more files, so you can not be as simple as in the logic package uses that unit. The advantage of physical encapsulation is that it can reduce maintenance, because each DLL is dynamically called, so we just need to update the corresponding DLLs we have changed, while the rest can be used without changes.
Encapsulate objects with DLLs:
With DLL encapsulation functions, I think almost all programmers are familiar with the technology that is no longer familiar, and we can find a lot of related books and materials. Here we only discuss how to encapsulate objects with DLLs.
Encapsulating objects with DLLs has the following benefits:
One, can save memory. We can load dynamically when using DLL resources and release when not in use.
Second, improve code reuse. After the DLL is encapsulated, we can invoke it using any of the development tools that support the DLL.
Third, the software can be split into a number of small pieces, which can effectively reduce the maintenance amount.
Note: If you use a dynamic library only to reduce the volume of software, then I suggest that you give up using the dynamic library.
Of course, it is also difficult to encapsulate objects with DLLs:
One, the EXE that calls the DLL can only use the method of dynamic binding of objects in the DLL.
Objects in a DLL can only be created in a DLL.
Third, both the DLL and the caller need to declare the encapsulated object and the called method.
Let's take a look at the following example:
First of all we declare a class:
type TNewClass = class(TObject) public procedureSayHello; virtual; // 注意,这里不能使用静态方法,必须使用动态绑定(或者说晚绑定)技术。 // 至于为什么——虚方法表有关,大家可以找其他资料详细研究^_^ end; procedureTNewClass.SayHello; // 实现部分begin ShowMessage(‘Hello‘);end; |
Create a new library project
librarydll; function GetObj: TNewClass; stdcall;begin // 创建对象 Result:= TNewClass.Create;end; exportsGetObj; // 定义输出函数end. |
Below, we create an EXE project and add the class declaration:
type TNewClass = class(TObject) public procedureSayHello; virtual; abstract; { 注意这里的声明方式和DLL中的不同,这里必须声明为virtual方法,还有由于此方法通过晚绑定用的是DLL中的实现,因此EXE中可不写其实现而声明成abstract方法。 } end;functionGetObj: TNewClass; stdcall; external ‘dll.dll‘; |
After that, we can add a test code to test whether we implement the common use of DLL objects:
var NewClass: TNewClass;begin NewClass:= GetObj; ifnot Assigned(NewClass) then Exit; try NewClass.SayHello; finally FreeAndNil(NewClass); end;end; |
As we can see, this does achieve the purpose of passing objects between EXE and DLL.
But, a bit of a hassle: First, both the DLL project and the EXE project need to have the definition of the encapsulated object. Second, virtual and abstract must be used correctly. Also, if the object changes, then both sides of the definition need to be modified, it will inevitably make a little mistake.
In fact, we can use the interface to carry out the object, the above example we can modify a little bit:
First, we define an interface:
type INewInterface = interface(IInterface) procedureSayHello(); // 定义我们要的方法 end; |
Also, modify the Tnewclass class's reputation:
type TNewClass = class(TInterfacedObject, INewInterface) public procedureSayHello(); end; |
The implementation section does not need to be changed.
Next, we modify the previous library project:
librarydll; function GetObj: INewInterface; stdcall;begin // 创建对象 Result:= TNewClass.Create;end; exportsGetObj; // 定义输出函数end. |
In the EXE project, we refer directly to the element defined by the interface and modify the declaration of the output function:
functionGetObj: INewInterface; stdcall; external ‘dll.dll‘; |
After that, the test code will be like this:
var NewInterface: INewInterface;begin NewInterface:= GetObj; NewInterface.SayHello; NewInterface:= nil;end; |
The advantage of this is that we can avoid repeating the declaration of an object to be passed in multiple places, as long as the method we need to declare is not moving, we only need to change the Tnewclass implementation code, without having to change any part of the code in the EXE program.
Ps:delphi's Opentoolsapi interface is a typical application of the principle of sharing objects through interfaces. (That's what Liu Yan said.) To be honest, this usage is what I thought of when I was writing this note because I never used a interface without a COM package. Where to know unexpectedly and opentoolapi the same principle, their yy under ^_^)
Of course we can also use COM to encapsulate objects:
First, we set up a COM model called newcom, and the COM model was built, and the previous one has said that it is not repeated here.
So, our calling code will look like this:
var NewCom: ITNewCom;begin NewCom:= CoTNewCom.Create; // 当然,和我前一篇一样使用CreateComObject函数也是一样的 NewCom.SayHello; NewCom:= nil;end; |
As we can see, there is little change in the implementation code. So, what if we're going to put SayHello's implementation code:
Change to:
MessageBox(0, ‘Hello‘, ‘SayHello‘, MB_OK); |
So, we just need to update this COM file, call its EXE program without modification, this is the advantages of the interface.
Delphi Object-oriented learning essay eight: Physical encapsulation