Posted by: Dave Rabelink
I have discovered a bug with dynalibs which i could not reproduce for
quite some time but now i have found it.
Sometimes a strange thing occurred. When a dynalib was initialised
with data and could be used by other dynalibs some of them actually
could get data from it, but others not. It seemed the initialised
dynalib suddenly cleared it's data as if it was not previously
initialised. I could not get a grip on the fact that within the
application some dynalibs could use the data as expected and at the
same time others could not. A workaround was to reshuffle the included
libraries and dynalibs within the sources (change the sequence of
including) which in most cases solved the problem.
After another strange issue with this i wanted to find what causes the
problem.
The reason for failure is a surprise for me :
Dynalib include declarations are CASE SENSITIVE !!
Let me explain.
Imagine there are two dynalibs and a main executable
Dynalib1.apd
Dynalib2.apd
Main.exe
Dynalib2.apd uses functionality/data from Dynalib1.apd and also
Main.exe uses this functionality directly from Dynalib1.apd.
The include declarations are :
Main.exe
Includes
Dynalib1.apd
Dynalib2.apd
Dynalib2.apd
Includes
Dynalib1.apd
Main calls Dynalib1.apd to initialise some global data, so
Dynalib1.apd holds data to be read. With an exported function of
Dynalib1 the data can be shown.
Dynalib2.apd also uses Dynalib1.apd. It wants to read the data from it
which is previously initialised by Main.
Normally this works ok. The data in Dynalib1 is initialised and both
Main and Dynalib2 can use it.
There is only one instance of Dynalib1 running, it holds the data
shared between Main and Dynalib2.
Surprisingly, if the declaration of the dynalib include in Main or
Dynalib2 does not correspond to eachother case wise, problems occur.
The next list of includes will reproduce the annoying bug :
Main.exe
Includes
Dynalib1.apd
Dynalib2.apd
Dynalib2.apd
Includes
dynalib1.apd
The only thing which was changed is that Dynalib2 now includes
dynalib1.apd instead of Dynalib1.apd (the first character is
lowercase). It does not matter if the filename of the dynalib itself
has different upper or lower case characters, i'm talking about the
way the filename of the dynalib is entered in the include section.
So, when there are differences in how the dynalib filename is entered
in the several sources within your application using dynalibs they
will not work properly.
My theory is this :
Normally a dynalib should be loaded just once. There should be only
once instance of the dynalib loaded so other dynalibs access the same
dynalib.
But at runtime, the name of the dynalib is used as a kind of label to
identify the dynalib.
So when Main.exe calls Dynalib1 in de above example, it will load
Dynalib1 and lables it as "Dynalib1.apd", as entered in the include
section.
Now, when later on Dynalib2 calls Dynalib1, it uses the label which is
entered in it's include section for the file and that is
"dynalib1.apd".
TD checks at runtime when Dynalib2 calls Dynalib1 if the dynalib with
the label "dynalib1.apd" was already loaded. Seems TD checks the
labels using CASE SENSITIVITY. It can not find the label as given and
loads Dynalib1. At that time there are two copies of Dynalib1 running
at the same time.
Main uses copy 1, Dynalib2 uses copy 2. That is the reason why Main
can read the initialised data from Dynalib1 without problems (Main has
loaded Dynalib1.apd itself and labeled it as "Dynalib1.apd". But
Dynalib2 uses not the same dynalib Main has started before, it has
loaded another one which is obviously not initialised. Therefore that
copy 2 will have no data.
I have made a simple sample to reproduce this bug. Try it to see that
the dynalib includes are case sensitive and causes the strange
behaviour.
This should not happen. Files are case insensitive in Windows. It
should not matter if i include DYNALIB1.apd or dyNaLiB1.ApD. It is the
same file and at designtime it treats it also as the same file. At
runtime TD actually does take the case into account.
I have supplied a ZIP file with the sample. Read the text file for
details.
Please try the sample and see in which versions this bug occurs.
The sample is created in TD3.1 PTF3, saved as text format.
Happily now i have found the reason for many strange issues with
vanishing data and other related effects using dynalibs.
Please confirm this can be reproduced as a bug at your setup and TD
version.
I have logged it as a bug, in a few days we will see what Gupta says
of this.
Regards,
Dave Rabelink