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)

x86
Windows NT
defect

Tracking

(Not tracked)

RESOLVED FIXED

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.
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.