delphi finalizalization code in a DLL - delphi

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 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..!

Related

Using IXMLDocument inside a DLL needs CoInitialize?

Is there ever a reason to use CoInitialize inside my DLL function when using IXMLDocument (msxml wrapper)? (or Other com object for that matter)
Is the calling application/thread responsible for calling CoInitialize/CoUninitialize?
What if I use ComObj inside my DLL which automatically calls CoInitialize in its initialization section and CoUninitialize in its finalization section?
Is the calling application/thread responsible for calling CoInitialize/CoUninitialize?
Yes. As a general rule, the creator of a thread must be responsible for initializing COM. Which means that the functions that you expose from your DLL should not initialize COM for the thread on which they were called.
The reason being that if you take responsibility for initializing COM in the thread that calls the DLL, then that places an unreasonable constraint on the creator of that thread. What if the creator of the thread needs to perform another action that requires COM to be initialized? The standard practise is that the DLL specifies COM initialization as one of its requirements. In the documentation for your DLL, state that the caller must initialize COM.
More details here: Things you shouldn't do, part 2: Dlls can't ever call CoInitialize* on the application’s thread.
That's why you should not initialize COM in your DLL on the caller's thread. There's even more reason not to initialize COM in an initialization section. Initialization sections are executed inside the DLL's DllMain. There are very few things that you are allowed to call inside DllMain, COM functions not being on the list of allowed actions. For more details: Some reasons not to do anything scary in your DllMain, part 3.
What if I use ComObj inside my DLL which automatically calls CoInitialize in its initialization section and CoUninitialize in its finalization section?
The ComObj unit does not do that. For a DLL, the COM initializing code that you refer to is suppressed. Including ComObj will force COM to be initialized in an executable project, but not in a library.

Is there some known unit who automatically initialize the COM Library when it's used?

I made a custom control that needs to use API DoDragDrop function and they say I must call OleInitialize before calling this function.
I do that in MyControl.Create method but I get S_FALSE result, so it means that the COM library is already initialized. But who initialize it ?
I do not initialize this before in my application. I am thinking, maybe there is some delphi unit who initialize it in his initialization section... And a secondary question is what should I do, should I continue initializing the COM Library in MyControl.Create method or should I not initialize at all (because it's already initialized) ?
As stated in my answer to a similar question:
In the RTL/VCL source, COM is initialized in the following ways:
By a call to OleInitialize made from Forms.TApplication.Create. So this call will be made for all VCL forms applications, but not, for
example, for service applications.
By a call to CoInitialize or CoInitializeEx in ComObj.InitComObj. This is registered as an InitProc in the
initialization section of the ComObj unit. In turn, the call to
Application.Initialize in your project .dpr file's code will invoke
ComObj.InitComObj.
In many and various other locations around the RTL/VCL. Including, but not limited to, Datasnap, ComServ, Soap, System.Win.Sensors,
Winapi.DirectShow9. Some of these areas of code are more recent than
Delphi 7.
Now, of these various COM initializations, the ones that count are 1
and 2. In any standard VCL forms application, both of these will run
at startup in the main thread. Item 1 runs first and so gets to
initialize COM first. That's the initialization that counts. Item 2
runs after and returns S_FALSE meaning that COM was already
initialized.
All VCL applications include the Forms unit and so you can be sure thaat COM is initialized in the main VCL thread. For other threads you need to initialize COM if necessary.
You must never initialize COM in control or more generally a thread that you are not in control of. If you do so then your initialization may conflict with the apartment type specified by the owner of the thread.

Using same mutex in host app and dll

I have a multithreaded application which dynamically loads dlls (plugins). I have threads in DLL. Between host app and dll is my own SDK which purpose is to enable communication with dll plugins (library interface) and to define shared resources between host app and dlls (data structures, etc..).
Host app is creating a mutex object with WinAPI function CreateMutex and passing a THandle of created mutex to every dll I load. When thread in DLL is changing common resources it uses mutex to protect it. As I said I am using WinAPI.Windows unit for calling CreateMutex and all other mutex related functions (Release etc..).
The idea is to make SDK cross-platform thus I am about to modify SDK and I would like to get rid off unit WinAPI.Windows and all Windows related stuff of course.
I included System.SyncObjs to use TMutex class. Now I am not quite sure how I would let know my dll's about that class. One option is to pass TMutex to my DLL but I think this is not an option if I want to keep primitve data types in my SDK because SDK must be available to other languages such as C++, C#... etc Other idea that crosses my mind is to use named mutexes and just pass a name (string) to DLL.
According to MSDN: If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
So I assume DLL will be able to use existing named mutex (MyMutex) when it will call TMutex.Create(...,'MyMutex').
Am I right?
Thank you for your help and your suggestions. I really appreciate it!
Windows mutexes can be "shared" across processes (and even more so in an exe and DLL) - you have two ways:
Use a named mutex. Use the OpenMutex() API to get the handle of an already existing mutex - you need to ensure it's called after CreateMutex() or it won't find the mutex to open.
Use DuplicateHandle() for an unnamed mutex, it returns a new handle valid in the target process (which can be the same, in the case of a DLL)
Often, the API wrapper in Delphi are too limited for "complex" scenarios. Using directly the Windows APIs will give you full access to the underlying functionalities, even if Delphi doesn't expose them. It turn, you will learn more about how Windows works, and it's a knowledge you can always recycle outside Delphi... and you don't need to use ugly hacks to wrap something that doesn't need to get wrapped in interfaces or the like...
If you need cross-platform capabilities, write your own wrappers for the OS mutex implementation - don't rely on the Delphi ones.
Passing a class instance between modules other than runtime packages is not allowed. That is not a valid form of interop.
So I think that the cleanest solution will be to wrap TMutex with an interface. You can pass interfaces between any type of module, even modules compiled by different compilers.
There are a variety of different mutexes available but in my view the obvious choice would be to wrap TMonitor. The interface is simple:
type
IMutex = interface
procedure Acquire; stdcall;
procedure Release; stdcall;
end;
It is perfectly safe to pass this interface between executables and DLLs.
The implementation might be as follows:
type
TXplatMutex = class(TInterfacedObject, IMutex)
public
procedure Acquire; stdcall;
procedure Release; stdcall;
end;
procedure TXplatMutex.Acquire;
begin
TMonitor.Enter(Self);
end;
procedure TXplatMutex.Release;
begin
TMonitor.Exit(Self);
end;
You can wrap any mutex you like in this way. I opted for TMonitor because it is supported on all platforms and is the main tool used by Embarcadero library code for synchronization.

LoadLibrary, a way to instantiate a class from external dll?

I have written a dll in d-7. It functions correctly. It gets loaded when an application starts and unloaded when it exists.
Now, that dll must also work on the server side of that application, being loaded from the COM+ surrogate (dllhost.exe) as the server is based on com+ technology.
The problem is that one process may have only one handle for loaded library. I cannot have separate handles on each LoadLibrary call.
In com+, one dllhost.exe can serve many clients, which means that if I load an external library it gives the same instance for each clients calls.
So:
1) Is it possible to somehow workaround this problem?
2) Or Is it possible to directly create instance of the class which resides in this dll for each client call?
3) Or How to make a dll thread-safe by instantiating an internal class for each call.
Thanks for suggestions in advance!
Since a DLL uses the local memory of the thread/process that calls it, I'm not sure you're really going to have a "problem". You do not want to have the DLL maintain some global information because that will only lead to threading nightmares.
If you have a function within the DLL return an object reference (effectively a handle) you can also guarantee that each instance gets its own information to play with and not stomp on other processes or threads. Define the function to return your TWhatever object, have the DLL create it ( TWhatever.Create() ) and return it to the calling process. It would then be up to the calling process to free the object. If you need COM+ compatibility then it should be possible to use an interface reference (IWhatever) and return that from your function.
If each thread deals with its own object instance (or interface reference) then you could have the DLL serve as many threads and processes as you wish.
Your question is confusing to me so I'm not sure if I answered it correctly. :p

Application.handle from DLL

Delphi.
How from DLL to learn Handle the appendix which has caused this DLL?
That is necessary: Knowing Handle appendices, I wish in Dll to use this Handle at creation of dialogues, because dialogue created as TOpendialog.Create(nil) sometimes it appears under the main window of the basic form. And so, in DLL I would make:
application.handle:=GetExeHandle; // GetExeHandle - How to learn?
Opendialog1:=TOpendialog.Create(application);
...
So it is correct?
The only time your DLL shows a dialog box is when the host application calls a function from your DLL. Include the parent window handle as one of the function's input parameters so that the EXE can tell you which handle to use. Do not attempt to discover the handle yourself. As a library developer, you cannot guess what the host application is doing.
If you don't want to include the handle on every function call, then add an initialization function that users of the DLL need to call before any other functions. Pass the handle in the initialization and then store it in a variable in your DLL so that other functions can use the value when they need it.
Unless you use runtime packages (and you don't, or not the right ones), you are in for a world of pain.
Your library will have its' own copy not only of (T)Application but also of thread sycnhronization queue and event (and everything else).
What you are trying to do can seem to work, but it may (and it will) break anytime cause any complex dialog, regardless if VCL or WinAPI, does its' own message pumping, which will bypass the applications' idle and synchronization handling, resulting in reentrancy issues and random stalls or deadlocks.
You may try to handle a lot of the cases by copying the applications' handles, events etc. to the DLL's globals upon its' initialization (is I tried to do), but (not only) if you use anything like TApplication or TThread in the DLL, it will break sometimes.
You can avoid these problems if you use the right BPL runtime packages in your app and the library, as they will share the same namespace and globals as the application using them.

Resources