开发者

delphi finalizalization code in a DLL

开发者 https://www.devze.com 2023-02-03 12:13 出处:网络
I am moving some functions to a shared DLL (I want to have some called as a Windows hook). The actual functions are currently in a unit, and it happens to have some initialization and some finalizati

I am moving some functions to a shared DLL (I want to have some called as a Windows hook).

The actual functions are currently in a unit, and it happens to have some initialization and some finalization code.

I was initially thinking on doing a direct transfor开发者_JAVA百科mation from a unit to a library. So I moved the initialization code in between the main begin and end.. But then I realized I had no place to move the finalization code. I should create and register an special DLL entry point, instead.

My question is. Can I leave the unit with all the functions and the initialization and finalization codes and just create a library stub that uses the unit? will the finalizationit be called?


Code in the initialization sections of the units in the DLL will run when the DLL is first loaded in to the process. The finalization sections fire when the DLL is unloaded from the process.

Eugene is right that you can have more fine-grained control using DLLProc but this is usually only needed for per-thread resources, e.g. thread local storage.

I would point out that there are serious limitations on what can be done during DLLMain which is ultimately where these initialization/finalization sections originate when inside a library. The MSDN documentation basically says that you can do some things, but that there is no list of acceptable behaviour. The closest it comes is to saying that you can call functions in kernel32. Otherwise, all bets are off!

There are lots of articles on the web that describe the issue, but beyond the MSDN topic for DLLMain that I've linked above, I would recommend reading Microsoft's Best Practices for Creating DLLs.

The helpful advice that MSDN offers is that the library can mandate that its users call an initialization function before using the DLL. A corresponding finalization function would be called once you were finished with the DLL. The use of comctl32.dll adopts this idiom, see InitCommonControlsEx.

In my own code I prefer an alternative approach. The initialization sections of all my units register initialization and finalization methods. Then, on the first call to any exported function from my library, the initialization methods are run, in the order in which they were registered. This is not a problem for me to implement because I am already controlling all entry/exit points to my library.

I realise this is more than you asked for, but you may find it helpful to avoid some rather hard to debug problems.


The initialization of a unit will be called if its a program and if its a library.

Same for the finalization.

So yes, you can leave the unit as it is and export the required functionality.


I'd suggest that you implement a DLLMain and handle different situations (process attach, thread attach etc) by calling dedicated procedures/functions for each situation. Then you can call the needed procedures/functions from initialization and finalization, if you need to switch from DLL to unit. The reason is that you might need some fine-grain control when the DLL is attached/detached to/from the thread (which will happen when you set a system-wide hook).


This happend to me as well. I found out that I had a unit, that initialization section that create a thread or doing some stuff, when the dll is registered.

I have removed this initialization section, and it worked fine.

Since, the initialization is required for .exe application but not for dll application, there is a variable flag in the system utility, called ModuleIsLib just do:

initialization

if not ModuleIsLib then
 begin
// initialization stuff for .exe file
 end;

This can be done also for finalization section as well.

hope it helped..!

0

精彩评论

暂无评论...
验证码 换一张
取 消