Explanation of Exporting Functions in Windows (105137)
The information in this article applies to:
- Microsoft Windows Software Development Kit (SDK) 3.0
- Microsoft Windows Software Development Kit (SDK) 3.1
This article was previously published under Q105137 SUMMARY
Exporting functions under Windows is one of the least understood but
most important concepts to understand. If string constants are garbage
or global variables contain the wrong information, then exported
functions are probably not doing their job. Exported functions simply
establish the correct data segment (DS) value on function entry.
MORE INFORMATION
Function entry point code, referred to as "prolog" code, does the work
of setting up all the registers on function entry. Exported prolog
code works with the Windows loader to support all the different
techniques of establishing DS. There are three types of exported
prolog code: loading DS from the value in AX, loading DS from the
value in SS, and loading DS from a hard-coded value fixed up by the
loader. The first two techniques are used in applications, the last is
used by dynamic-link libraries.
Loading DS from the Value in AX
This is the classic application exporting technique. This works with
the MakeProcInstance function, which loads the correct DS value into
AX before calling the exported function's prolog code. As an
application is loaded, all exported functions built with the -Gw
switch or -GA -GEa pair are modified so that the first 3 bytes of
prolog code are NOPs. The following prolog code sets up the stack
frame and finally loads DS from the value in AX. In mixed mode, it
would appear as follows:
{
nop
nop
nop
push bp
mov bp,sp
push ds
mov ds,ax
Loading DS from the Value in SS
This is a more recent technique that assumes that the SS register
contains the correct DS value on function entry. For applications that
don't switch their stack segment nor are called from other
applications, this is a valid assumption. The -GA default code loads
DS from the value in SS without the loader required to fix up the
prolog code. In mixed mode, it would appear as follows:
{
mov ax,ss
push bp
mov bp,sp
push ds
mov ds,ax
Loading DS from a Hard-Coded Value
This is the classic dynamic-link library exported function prolog
code. Because libraries are single instance, it's possible to get away
with hard-coded values to establish DS. As a library is loaded, all
exported functions built with -Gw or -GD are fixed up to load DS from
a hard-coded value. In mixed mode, it appears as follows:
{
mov ax,????
push bp
mov bp,sp
push ds
mov ds,ax
In the two techniques that involve the loader, an EXPDEF record must
appear in the EXE header for the exported function. This can be done
by the classic EXPORTS statement in the module definition file (.DEF)
or via the -GEe compiler switch. At a minimum, the newer switches
require the __export keyword to brand exported functions at compile
time or the -GEf switch (which brands all far functions as __export).
An example of the use of the __export keyword is as follows:
void CALLBACK __export TheExportedFunction()
Modification Type: | Major | Last Reviewed: | 6/24/2004 |
---|
Keywords: | kb16bitonly KB105137 |
---|
|