Closed
Bug 66374
Opened 24 years ago
Closed 24 years ago
information about linking to DLLs by name or by ordinal
Categories
(NSPR :: NSPR, defect, P3)
Tracking
(Not tracked)
RESOLVED
FIXED
4.1
People
(Reporter: nelson, Assigned: nelson)
Details
his "bug" is a repository for information about creating and linking
with DLLs on Win32 platforms. This is information that was not easily
obtained from the MSDN web site.
The MSDN web page
http://msdn.microsoft.com/library/devprods/vs6/visualc/vccore/_core_export_from_
a_dll.htm
says "When exporting functions with either method, make sure to use the
__stdcall calling convention." But it does not say why this should be done
or what will happen if you don't.
The answer is that all Microsoft's programming languages besides c/c++
use the __stdcall calling convention, so if you don't use __stdcall,
the functions will only be callable from other c/c++ code, and not from
(say) Visual Basic code.
The MSDN web page
http://msdn.microsoft.com/library/devprods/vs6/visualc/vccore/_core___stdcall.ht
m
says "The /Gz compiler option specifies __stdcall for all functions not
explicitly declared with a different calling convention. "
The page
http://msdn.microsoft.com/library/devprods/vs6/visualc/vccore/_core_determine_wh
ich_exporting_method_to_use.htm
states "Exporting functions in a .DEF file gives you control over what
the export ordinals are. When you add additional exported functions to
your DLL, you can assign them higher ordinal values (higher than any
other exported function). When you do this, applications using
implicit linking do not have to relink with the new import library that
contains the new functions. This is very important, for example, if
you are designing a third-party DLL for use by many applications. You
can continue to enhance your DLL by adding additional functionality
while at the same time ensuring that existing applications will
continue to work properly with the new DLL."
The implication of that paragraph seems to be that if you don't control
your ordinals explicitly, you will not have compatibility between old
applications and newer DLLs.
Nomenclature:
Microsoft DLLs have two ways to access exported symbols: by name and by
ordinal. Ordinals are effectively an index into the DLL's table of
addresses of exported symbols. Each symbol in the table usually has a
name string attached to it, but the name strings may be suppressed, in
which case the symbols are only accessible by ordinal.
Exported DLL symbols may be accessed from within an application by
either of two means: "Implicit linking" which is address resolution
done by the linker at link time, using the "import library" that goes
with the DLL, and "Explicit linking", which is where the application
gets the address of the exported symbol by calling GetProcAddress
(analogous to dlsym() on Unix) at run time.
The second argument to GetProcAddress may be a pointer to a name string
or may be a short integer (cast as a pointer). A short integer is
taken to be an ordinal. This is how a program accomplishes symbol
resolution by name or by ordinal at run time.
For "implicit" linking, the application calls the external function by
name and the call is resolved by linking with the DLL's "import
library", which is a static library that contains code that knows how
to access the DLL entry point, either by name or by ordinal.
What I discovered:
Whether the code in the "import library" accesses a DLL symbol by name
or by ordinal is determined at the time the DLL and import library are
built. If the DLL was built using a .DEF file and the .DEF file
contained an explicit ordinal number for a symbol, using the @N syntax,
then the import library will access that symbol by ordinal at run
time. If no .DEF file was used to generate the DLL (e.g. if
__declspec(dllexport) was used in the sources to identify the exported
symbols), or if the symbol was given in a .DEF file but without any
explicit ordinal number, then the import library will access the symbol
by name.
A symbol cannot be accessed by ordinal via "implicit linking" unless it
has been given an explicit ordinal in a .DEF file. But a symbol can
always be accessed by ordinal via "explicit linking", even when it has
not been given an ordinal explicitly.
The NONAME keyword in a .DEF file is ignored unless an explicit ordinal
is given. When both are present, the name string for the symbol is
suppressed (not present in the DLL), making the symbol only accessible
by ordinal, not by name, at run time.
All DLL exported symbols have ordinals. When symbols do not have
explicit ordinals assigned to them in a .DEF file, ordinals are
assigned to them using the following algorithm. The symbols without
explicit ordinals are sorted in alphanumerical order. The ordinal of
the first symbol in the alphabetized list is either the highest
explicitly assigned ordinal plus 1, or the number 1 if no explicit
ordinals were given. All the subsequent names in the alphabetized list
receive successive integer numbers.
Ordinals are unsigned 16 bit numbers, so ordinal numbers may not exceed
64k-1.
Comment 1•24 years ago
|
||
We have determined that it is fine to not assign ordinals
to the exported functions. Closed the bug.
Status: NEW → RESOLVED
Closed: 24 years ago
Priority: -- → P3
Resolution: --- → FIXED
Target Milestone: --- → 4.1
You need to log in
before you can comment on or make changes to this bug.
Description
•