Microsoft KB Archive/172393

= PRB: Can't Export Symbols Differing Only by Leading Underscores =

Article ID: 172393

Article Last Modified on 9/23/2003

-

APPLIES TO

 The Linker (LINK.EXE), when used with:  Microsoft Visual C++ 4.0 Standard Edition

 Microsoft Visual C++ 4.0 Standard Edition

 Microsoft Visual C++ 4.1 Subscription

 Microsoft Visual C++ 4.2 Professional Edition</li></ul>

 Microsoft Visual C++ 4.2 Enterprise Edition</li></ul>

 Microsoft Visual C++ 5.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 6.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 4.2 Professional Edition</li></ul>

 Microsoft Visual C++ 5.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Standard Edition</li></ul>

 Microsoft Visual C++ .NET 2002 Standard Edition</li></ul>

<ul> <li>Microsoft Visual C++ .NET 2003 Standard Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q172393

<div class="symptoms_section">

SYMPTOMS
When you are using the linker supplied with the Visual C++ compiler versions mentioned above to build a DLL and the following applies:
 * 1) You export multiple symbols from a DLL.
 * 2) The symbols differ only by the number of leading underscores or by the number of leading question marks.
 * 3) The first letter in the symbol is uppercase.
 * 4) The symbols are located in an assembly source file.

Then, the Visual C++ linker incorrectly matches some of the symbol names.

<div class="resolution_section">

RESOLUTION
There are several workarounds: <ul> <li>Do not use leading underscores or leading question marks to differentiate between different symbols. -or-

</li> <li>Use Visual C or Visual C++ instead of assembly. -or-

</li> <li>Use aliases in the EXPORTS section of the .def file as shown below. The left-hand side of the "=" symbol is the name of the function that is exported by the DLL and an external application/DLL can call. The right- hand side is the symbol the linker will use to match during the link phase. Note the missing underscore on the right hand side symbol.

EXPORTS

_symbol1=symbol1

Use the following link command to build the DLL:

link -dll -out:MYDLL.LIB -def:MYDLL.DEF MYDLL.OBJ

</li></ul>

<div class="status_section">

STATUS
This behavior is by design.

<div class="moreinformation_section">

MORE INFORMATION
The following sample code is used to demonstrate the third (last listed) workaround. The "-noentry" option is used for the linker in this sample because no entry point function is defined for the DLL. The "-map" option is used for comparison with the DUMPBIN output of exported symbols.

Assembler options needed: /nologo /coff /Cx /c

Linker options: -dll -noentry -map -out:MYDLL.LIB -def:MYDLL.DEF \ MYDLL.OBJ TITLE   mydll.asm

.386 .MODEL flat, SYSCALL

.CODE

Nosymbol PROC ret Nosymbol ENDP

_symbol PROC ret _symbol ENDP __symbol PROC ret __symbol ENDP

___symbol PROC ret ___symbol ENDP

____symbol PROC ret ____symbol ENDP

_symbol1 PROC ret _symbol1 ENDP

__symbol2 PROC ret __symbol2 ENDP

___symbol3 PROC ret ___symbol3 ENDP

____symbol4 PROC ret ____symbol4 ENDP

END Use the following module definition file to build the DLL: ; The module definition file MYDLL.DEF

EXPORTS Nosymbol

_symbol=symbol __symbol=_symbol ___symbol=__symbol ____symbol=___symbol

_symbol1=symbol1 __symbol2=_symbol2 ___symbol3=__symbol3 ____symbol4=___symbol4 Following are the contents of the mydll.map file: <pre class="fixed_text">mydll

Timestamp is 33e12fbb (Thu Jul 31 17:37:15 1997)

Preferred load address is 10000000

Start        Length     Name                   Class 0001:00000000 00000009H .text                  CODE 0002:00000000 000000e5H .edata                 DATA

Address        Publics by Value              Rva+Base   Lib:Object

0001:00000000      Nosymbol                   10001000 f mydll.obj 0001:00000001      _symbol                    10001001 f mydll.obj 0001:00000002      __symbol                   10001002 f mydll.obj 0001:00000003      ___symbol                  10001003 f mydll.obj 0001:00000004      ____symbol                 10001004 f mydll.obj 0001:00000005      _symbol1                   10001005 f mydll.obj 0001:00000006      __symbol2                  10001006 f mydll.obj 0001:00000007      ___symbol3                 10001007 f mydll.obj 0001:00000008      ____symbol4                10001008 f mydll.obj

entry point at       0000:00000000

Static symbols Compare the symbols of the above map file output with that of the "DUMPBIN /exports mydll.dll" output below. <pre class="fixed_text">Microsoft (R) COFF Binary File Dumper Version 5.00.7022 Copyright (C) Microsoft Corp 1992-1997. All rights reserved. <BR/><BR/>

Dump of file mydll.dll <BR/><BR/>

File Type: DLL

Section contains the following Exports for mydll.dll

0 characteristics 33E12FBA time date stamp Thu Jul 31 17:37:14 1997 0.00 version 1 ordinal base 9 number of functions 9 number of names

ordinal hint  name

1   0   Nosymbol  (00001000) 2   1   ____symbol  (00001004) 3   2   ____symbol4  (00001008) 4   3   ___symbol  (00001003) 5   4   ___symbol3  (00001007) 6   5   __symbol  (00001002) 7   6   __symbol2  (00001006) 8   7   _symbol  (00001001) 9   8   _symbol1  (00001005)

Summary

1000 .rdata 1000 .reloc 1000 .text

Keywords: kbprb KB172393

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.