home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Accessing Global Variables Across DLL
- --------------------------------------
-
- In lasts months WPJ I wrote an introductory DLL article. This
- month I wish to share with the many readers of the WPJ (at least that's
- what Pete and Mike keep telling us) of a way that I discovered by necessity
- of handling global variables across DLLs. I describe my approach as a 'kludge'
- but, to me it is a fairly good 'kludge'. Like anything done against the norm
- there are some risks; like receiving flammable E-mail about going against
- Windows standards, and possibilities that Microsoft will change some things
- and therefore in later versions my approach will not work. All of these are
- possibilities but, I can live with those for now. Why? Because I think that
- it is a feasible kludge and what I will show you is nothing that Windows has
- not been doing since version 2.0 and it has not changed yet. That is not to
- say that they will not change, but that for now it seems safe to say that
- they will not.
-
- Here's some background information on why I chose to use the method
- I came up with. Windows already supplies ways of handling global variables
- across DLLs, for instance, shared memory, passing far pointers and redeclaring
- the variables in the DLL. These methods are workable and I strongly suggest
- that they be used. Well, here's the background. I was given the task of
- converting two DOS applications over to Windows and making them into one
- package. My mission was to get it up and running as quickly as possible. The
- original DOS application made use of numerous global variables. So, I decided
- to do a straight port, and after demoing the port and management making their
- decision, I would convert the App over to DLLs. Well, the first two steps
- (ported and mgmt. decision) were completed 7 months later. So, now the big
- job was to fix up everything over to DLLs. This was no problem except for
- the numerous global variables. Hind sight told me I was stupid for not
- dealing with them initially. Handling the global variables the way
- Microsoft suggests would mean that a great portion of the code would have
- to be rewritten, and you know that there just is never any time to do that.
- So, I began to think to myself, and I remembered reading about Micheal Geary's
- FIXDS. The same logic he applied to not having to call 'MakeProcInstance' also
- applied to what I was thinking.
-
- The stack segment (SS) for DLLs is that of the calling application.
- And, the calling apps. DS == SS. Therefore, any global variables (CONST and
- BSS) defined in the application is shared with the DLL via SS. The only
- problem is that you have no clear way of accessing those variables. In
- Windows global variables in segments do not change their offsets, only the
- segments can be changed due to memory management. Thus, the offset values of
- the global variables will always be at the same location inside the
- segment. Knowing this, how do we determine those offsets? The answer is the
- MAP file that the compiler will supply for you. The MAP file lists all
- global symbols defined in the object file(s), sorted by name and a list
- sorted by address. With this information in hand we can make a file of all
- the global variables used in the program. The global list should use the
- same case as the actual definitions. Also, since the MAP file sorts the variables
- by name and thats what we are looking for, the matching variable names and
- their offsets, our list file should be sorted, this will speed the search.
- I wrote a utility program that I call "getoff.exe", that searches the MAP
- file and creates an output constants file of the variables, i.e.,
-
- GLOBAL HEADER FILE INPUT FILE FORMAT OUTPUT FILE FORMAT
- ------------------ ----------------- -------------------
- int variableA; variableA #define VARIABLEA 0x0001
- int variableB; variableB #define VARIABLEB 0x0002
- int variableC; variableC #define VARIABLEC 0x0003
-
- The outputed constant file is to be inlcuded in the DLL modules.
- I forgot to mention one thing. The global variables must be declared inside
- the DLLs also. The cleanest way would be to include them in a
- global header file. Now with the use of some in-line assembly code the global
- variables can be accessed and updated inside the DLL.
-
- #include "consts.h"
- #include "global.h"
- .
- .
- .
-
- /* this code sets up the variables inside the DLL */
- _asm mov ax, ss:[VARIABLEA]
- _asm mov [variableA], ax
-
- _asm mov ax, ss:[VARIABLEB]
- _asm mov [variableB], ax
-
- _asm mov ax, ss:[VARIABLEC]
- _asm mov [variableC], ax
-
- /* now use the variables like normal */
- variableC= variableB;
- variableB= variableA;
- variableA= variableC;
-
- /* when finish reasign the values to the global */
- /* variables defined in the application */
- _asm mov ax, [variableA]
- _asm mov ss:[VARIABLEA], ax
-
- _asm mov ax, [variableB]
- _asm mov ss:[VARIABLEB], ax
-
- _asm mov ax, [variableC]
- _asm mov ss:[VARIABLEC], ax
-
-
- This is all it takes to accomplish the task of using global variables
- across DLLs. I created for my companies purposes entry/exit routines that
- handle the assigning and re-assigning of the variables, only because our
- application has over some 75 to 100 global variables.
-
- Included with this document is the "getoff.exe" utility and its
- source, and source and executable example of a DLL accessing a global
- variable. To run "getoff" type 'getoff <mapfile name> <input file>'.
- As I stated this is only a kludge, this method should only be
- used if you do not have time to rewrite code and you have too many global
- variables. If you have the fortunate pleasure of creating your own application
- try to stay away from global variables, and if you must handle them the way
- Microsoft suggests.
-
- Rod Haxton can be reached at (703) 883-0226 or (202) 269-3780.
-
-
-
-