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 transformation 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 finalization
it 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With