DLL leads to the class - Delphi actual combat

zhaozj2021-02-11  203

DLL leads to the class - Delphi actual combat

Author: Musicwind®

Creation time: 2001-11-01

~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

Update history: NO.1

Updated: 2001-11-01 20:09

Update person: MusicWind®

Update Note: The first draft is complete.

~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

Summary:

This article discusses how to guide out classifications in DLL - based on a particular abstract class. This technology uses polymorphism, so that we get the effect similar to the plugin.

Expected readers:

Understand the concept of polymorphism; understand the concept of the metaciety.

technical difficulty:

6/10.

From the DLL, you will first think of the BPL package first. This way is a bad thing, that is, the user must know those classes in this package, which means that the name of the class must know - this is a constraint in a certain sense, tries that the user defines a bottom layer. Abstract class, then define a number of applications (Concrete Class) on this, so he wants to use these classes without knowing what kinds of categories do not know. It seems that there seems to be some mysterious, but the actual situation is indeed, because when defining the abstract class, it is not expected to have a specific class in the future - then such a need, depending on what technology is implemented?

In fact, the difficulty of implementing technology is not big - the author is dedicated to everyone, calculating a brick, hoping to see other better ways!

The following first introduces some of the basic knowledge involved, and then use an example to illustrate the specific implementation.

First, basic concept

Meta Class, also called class-reference type, can be seen as a type of type, with a value of the variable of this type, represents a class. such as:

Type

TCLASS = Class of TOBJECT;

This declares a type of class class. You can then have such variables:

VAR

ACLASS: TCLASS;

So, you can have this usage:

ACLASS: = TOBJECT;

or:

Aclass: = tbutton;

or:

Aclass: = TFORM;

and many more.

Because TCLASS is a Tobject type of category, and TButton, TFORM, etc. are derived from Tobject, so TButton and TFORM are acceptable for ACLASS.

Then we can use polymorphic ideas and flexibly use the ACLASS variable. This is also the basis knowledge implemented below.

Second, the specific implementation

The first step is to create an abstract class:

We use such a simple statement that this abstract class only provides an abstract method, but does not affect our description:

TMYBASEFORM = Class (TFORM)

protected

Function GetTitle: Pchar; Virtual; ABSTRACT;

END;

MyBaseformClass = Class of Tmybaseform;

There is no discussion for such an abstract approach to a practical method and interface for such an abstract class because we want to discuss a technical feasibility. Suppose the author defines the original intention of this interface only wants to get any multi-change Title, and the return value of the specific GetTitle requires the reintegration. Also, the author also hopes that the code of the subclass is implemented in the DLL. Separate with the main program - this way is very plug-in taste, perhaps certain features of PLUG & Play - Is it quite attractive? So, what should I do next? First, the main program and the DLL program should include the units of the above declarations, and then, the main program is responsible for implementing a drive-dynamically loaded DLL, dynamically loaded; and the DLL is responsible for implementing a subclass.

Let's talk about DLL first, what do DLL should do?

In the second step, the DLL is exported:

We have designed two export functions:

1. Function getClassCount: integer; stdcall;

Tell the caller, there are several subclasses in this DLL;

2. Function getClasStypebyindex (const IIndex: integer;

VAR ClassType: MyBaseformClass: WordBool; stdcall;

Get specific subclasses in an indexed manner. Note that the type of ClassType here is MyBaseformClass, which indicates that its value will be a class that is determined from TMYBASEForm.

The following is a possible implementation:

Function getClassCount: Integer;

Begin

Result: = 3; // Indicates that 3 classes are exported in this DLL

END;

Function getClasStypebyindex (const IIndex: integer;

VAR ClassType: MyBaseformClass: WordBool;

Begin

RESULT: = true;

Case IIndex of

0: ClassType: = tfrmtest1;

1: ClassType: = tfrmtest2;

2: ClassType: = tfrmtest3;

Else

Result: = FALSE;

END;

END;

Of course, the units of TFRMTEST1, TFRMTEST2, and TFRMTest3 should be included in the USE list of the unit. The implementation of TFRMTEST1 can be like this:

Tfrmtest1 = Class (TMYBASEFORM)

protected

Function GetTitle: pchar; override;

END;

Function tfrmtest1.gettitle: pchar;

Begin

Result: = 'Hello from tfrmtest1';

END;

At the end, don't forget to add GetClassCount and getClassByIndex to the Exports list. Then, when Build This DLL project, "Use the Run Pack Use Runtime Package" in Project Option-Package. As for the specific reason.

At this point, the work in DLL comes from a paragraph.

In the third step, the implementation of the main program driver engine:

This step is relatively easy - nothing more than dynamically loading the DLL, then call the getClassCount function, then call GetClassbyIndex. Key code:

VAR ACLASS: TMYBASECLASS;

AFORM: TMYBASEFORM;

I, ICOUNT: INTEGER;

Blresult: boolean;

Begin

// Slight to the part of the dynamic library, assume that the fpgetclassproc points to the getClassCount function, and FpGetClassByIndexProc points to getClassByIndex, then:

ICOUNT: = fpgetclassproc;

For i: = 0 to ICOUNT - 1 DO

Begin

Aclass: = fpgetclassbyindex (i, blresult);

IF blsult then

Begin

AFORM: = ACLASS.CREATE (Application);

AFORM.CAPTION: = AFORM.GETTITLE;

AFORM.SHOW;

END;

END;

// ...

END;

Pay attention to a point, and the DLL is similar, when you create an output file, you also need to choose to use the running time package. This is because if a running time package is not used, there will be multiple copies of the same class in memory, thus returning the result of False using the IS operator.

MusicWind®@hangzhou.zhejiang.china

2001-11-01

More articles

Culture

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

New Post(0)