The DLL that you are building contains your Ada code as well as all the routines in the Ada library that are needed by it. The first thing a user of your DLL must do is elaborate the Ada code (see Elaboration Order Handling in GNAT).
To achieve this you must export an initialization routine
(Initialize_API
in the previous example), which must be invoked
before using any of the DLL services. This elaboration routine must call
the Ada elaboration routine adainit
generated by the GNAT binder
(see Binding with Non-Ada Main Programs). See the body of
Initialize_Api
for an example. Note that the GNAT binder is
automatically invoked during the DLL build process by the gnatdll
tool (see Using gnatdll).
When a DLL is loaded, Windows systematically invokes a routine called
DllMain
. It would therefore be possible to call adainit
directly from DllMain
without having to provide an explicit
initialization routine. Unfortunately, it is not possible to call
adainit
from the DllMain
if your program has library level
tasks because access to the DllMain
entry point is serialized by
the system (that is, only a single thread can execute “through” it at a
time), which means that the GNAT run time will deadlock waiting for the
newly created task to complete its initialization.