Delphi

zhaozj2021-02-17  51

Author: Zou E-mail: zouf.tech@ATechSoft.comHomepage: http: //www.atechsoft.com/people/zouf/

There is a lot of strange problems in the process of delphi, and the Delphi's document is also surprisingly, so it can only sum up itself, so there is a copy below (because the details are just zero, there is no flower Maybe it is more chaotic, but it should be able to understand ;-)).

in case:

1. You have a better solution for the following questions, please tell me, friends on 9CBS.

2. You have other questions, please list questions, as well as your answer, tell me, and friends on 9CBS.

Communication and create everything! text:

Q: FORM made in Delphi's DLL, if ShowModal is in Exe, two icon appears on the taskbar, why? how to solve this problem?

A: Below is a typical method of adding FORM in DLL:

DLL:

Function Showfrm: TMODALRESULT; STDCALL;

Begin

FORM1: = TFORM1.CREATE (NIL);

Try

Form1.ShowModal;

Finally

Form1.free;

END;

END;

Main EXE:

Function Showfrm: TMODALRESULT; stdcall; External 'Testdll.dll';

...

Begin

...

Showfrm;

...

End.

In this way, the FORM in the DLL, the main application displays another icon, why is there:

Delphi will be created another application for the DLL, and each Application displays icon of a taskbar.

Solution:

In the primary application, the Application of the primary EXE is incorporated into the DLL, as follows:

DLL:

Function Showfrm (app: tapplication): TMODALRESULT; stdcall;

VAR

Oldapp: Tapplication;

Begin

Oldapp: = Application;

Application: = app;

FORM1: = TFORM1.CREATE (NIL);

Try

Form1.ShowModal;

Finally

Form1.free;

END;

Application: = OLDAPP;

END;

Main EXE:

Function ShowFRM (App: Tapplication): TMODALRESULT; stdcall; external 'testdll.dll';

...

Begin

...

Showfrm (Application);

...

End.

Note: Application and EXE in the DLL are still some differences, see the code in Forms.PAS:

Constructor TAPPLICATION.CREATE (Aowner: Tcomponent);

Begin

...

IF not islibrary the cretehandle;

...

END;

You can know that Application in the DLL doesn't have a handle, so there is no message loop processing, which is also very correct.

Q: DLL in Delphi, often there is a problem! A: So there is a problem because of the memory management mechanism of Delphi itself. such as:

Create an object in the DLL:

x: = tclass.create (application);

At this time, Delphi automatically free X when Application Free, but since X is in the address space of the DLL, the address space of the DLL may have failed (different operating systems), so at this time The release operation of X will cause an exception.

Another example:

An object is created in EXE and passes the DLL as partial variable in the DLL, so that when DLL is destroyed, since Delphi is automatically released, if this object is used in EXE, It will cause an exception.

In general, the problem is due to the "smart" Delphi compiler's memory management mechanism, and Windows DLL plus / unloading mechanism, there is a memory access conflict in DLL and EXE.

Solution: (as long as you follow the following principles, you can avoid most of the questions)

1. Between DLL and EXE, try not to use Delphi's automatic memory management mechanism, which is responsible for the life of the object, such as:

For the x: = tclass.create (application); put it:

x: = tclass.create (nil);

In this way, Application will not free it. Of course, programmers must release it.

2. Try to avoid the same object to point to different pointers between DLL and EXE. For example, there is X point to the TCLASS object in the DLL, in Exe, which point to the Tclass object, so that memory release on any side will cause the other side to be invalid.

3. other…

Q: A thread that is a cyclical task, where you need to pause, then continue to run, but if you need to stop the thread (for example, the process is over)?

A:

Solution 1:

Periodic cycle is performed through the SLEEP in the thread. (If you are suspended in the thread, it is impossible to resurrect threads by RESUME.

End the thread by killthread.

This is the easiest way, but it is too rude, it may cause problems (Killthread is the API that Windows is not recommended)

Solution 2:

In the thread, Suspend, through a timer outside the thread, RESUME is every other period of time. code show as below:

// thread

Procedure execute;

Begin

While Not Terminated DO

Begin

... // Processing code

Suspend;

END;

END;

/ / Outside

// timer

Procedure Ontimer (Sender: TOBJECT);

Begin

THD.RESUME;

END;

// To end the thread

...

THD.RESUME;

THD.TERMINATE;

THD.WAITFOR; // Generally, after the end thread has to confirm the thread is really ended.

...

Problem: Thread and external coupling are too strong, even threaded operation cycles can be determined by the outer timer.

Solution three (this is the best way I think): Pause the operation through the signal in the thread.

// thread

Tmythread = Class (TTHREAD)

Private

Event: TEVENT;

protected

Procedure execute; override;

public

Constructor Create (LoginInfo: TloginInfo; OVERLOAD;

DESTRUCTOR DESTROY; OVERRIDE;

Procedure set

END;

{TMYTHREAD}

Constructor Tmythread.create (LoginInfo: TloginInfo);

Begin

Event: = TEVENT.CREATE (NIL, TRUE, TRUE, 'EventName');

END;

DEStructor Tmythread.Destroy;

Begin

Event.Free;

inherited;

END;

Procedure Tmythread.execute;

Begin

inherited;

While Not Terminated DO

Begin

// ...

Event.resetEvent;

Event.waitfor (10000);

END;

END;

PROCEDURE TMYTHREAD.SETEVENT;

Begin

Event.sevent;

END;

For programs that need to interrupt threads, you only need to code as follows:

Begin

...

THD.TERMINATE;

THD.SETEVENT;

THD.WAITFOR;

...

END;

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

New Post(0)