home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Examples / WinTools / TDUMP.TXT < prev    next >
Encoding:
Text File  |  1999-01-26  |  60.5 KB  |  1,542 lines

  1. TDUMP Help
  2.  
  3. 1.  TDUMP: The file inspecting utility
  4. 2.  Understanding "Undefined Symbol" Error Messages
  5. 3.  Resolving Undefined Symbol linker messages
  6. 4.  Borland Open Architecture: Name Mangling
  7.  
  8.  
  9. ===================================================================
  10. 1.  TDUMP: The file inspecting utility
  11. ===================================================================
  12. TDUMP.EXE is a utility that you use to examine the structure and
  13. contents of files.
  14.  
  15. TDUMP organizes the output display according to the extension of the
  16. file you're dumping. If the file extension is recognizable, TDUMP
  17. displays the file's components according to the file type. TDUMP
  18. recognizes many file extensions, including .EXE, .OBJ, and .LIB files.
  19. If TDUMP doesn't recognize an extension, it produces a hexadecimal dump
  20. of the file. You can control the output format by using command-line
  21. options when you start the TDUMP (these command-line options are
  22. described later).
  23.  
  24.  
  25. TDUMP syntax
  26. ------------
  27. The syntax for TDUMP is:
  28.  
  29.   TDUMP [<options>] <Inputfile> [<Listfile>] [<options>]
  30.  
  31.   o  <options> stands for any of the TDUMP options discussed in the
  32.      next section. For a list of the available command-line options,
  33.      type TDUMP, then press <Enter> at the DOS prompt.
  34.  
  35.   o  <Inputfile> is the file whose structure you want to display (or
  36.      "dump").
  37.  
  38.   o  <Listfile> is an optional output file name. Note that you can
  39.      also use the standard DOS redirection command ">" to create an
  40.      output file.
  41.  
  42.  
  43. TDUMP command-line options
  44. --------------------------
  45.  
  46. You can use several optional switches with TDUMP, all of which start with a hyphen or a forward slash. The following two examples are equivalent:
  47.  
  48.     TDUMP -el -v demo.exe
  49.     TDUMP /el /v demo.exe
  50.  
  51. The -a and -a7 options
  52.  
  53. TDUMP automatically adjusts its output display according to the file type. You can force a file to be displayed as ASCII by including the -a or -a7 option.
  54.  
  55.   -a  produces an ASCII file display, which shows the offset and the contents in displayable ASCII characters. A character that is not displayable (like a control character) appears as a period.
  56.  
  57.   -a7 converts high-ASCII characters to their low-ASCII equivalents. This is useful if the file you are dumping sets high-ASCII characters as flags (WordStar files do this).
  58.  
  59. The -b# option
  60.  
  61. The -b# option allows you to display information beginning at a specified offset. For example, if you wanted a dump of MYFILE starting from offset 100, you would use:
  62.  
  63.     TDUMP -b100 MYFILE
  64.  
  65. The -C option
  66.  
  67. The -C option causes TDUMP to dump information found in COFF format files (.OBJ and .LIB). This option is useful when linking with Microsoft .OBJ and .LIB files.
  68.  
  69. The -d option
  70.  
  71. The -d option causes TDUMP to dump any Borland 32-bit debug information found in the .OBJ file. If you do not specify this option, TDUMP displays raw data only.
  72.  
  73. The -e, -el, -er and -ex options
  74.  
  75. All four options force TDUMP to display the file as an executable (.EXE) file.
  76.  
  77. An .EXE file display consists of information contained within a file that is used by the operating system when loading a file. If symbolic debugging information is present (Turbo Debugger or Microsoft CodeView), TDUMP displays it.
  78.  
  79. TDUMP displays information for DOS executable files, NEW style executable files ( Microsoft Windows and OS/2 .EXEs and DLLs ), Linear Executable files, and Portable Executable (PE) files used by Windows NT and Windows 95.
  80.  
  81.     -e Display file as Executable (EXE/DLL, DOS, Win16, OS/2, PE)
  82.     -ea[:v] Display All Exports unsorted, or (:v) sort by RVA (default dumps only named exports, sorting on the name)
  83.     -ed Disable EXE debug information
  84.     -ee[=x] List Exports only from EXE/DLL (optional x lists matches only)
  85.     -el suppresses line numbers in the display
  86.     -eiID   Include only .EXE table ID (HDR, OBJ, FIX, NAM, ENT)
  87.  
  88.     -em[=x] List Imports only from EXE/DLL (optional x lists matches only)
  89.     -em.[x] List Imported modules only from EXE/DLL (optional x search string)
  90.     -ep Disable EXE PE header display
  91.     -er prevents the relocation table from displaying
  92.     -ex prevents the display of New style executable information. This means TDUMP only displays information for the DOS "stub" program
  93.  
  94. The -h option
  95.  
  96. The -h option displays the dump file in hexadecimal (hex) format. Hex format consists of a column of offset numbers, 16 columns of hex numbers, and their ASCII equivalents (a period appears where no displayable ASCII character occurs).
  97.  
  98. If TDUMP doesn't recognize the input file's extension, it displays the file in hex format (unless an option is used to indicate another format).
  99.  
  100. The -i option
  101.  
  102. The -i<id> option is used to specify the debug table(s) to use
  103.  
  104. The -l, -li and -le options
  105.  
  106. The -l option displays the output file in library (.LIB) file format. A library file is a collection of object files (see the -o option for more on object files). The library file dump displays library-specific information, object files, and records in the object file.
  107.  
  108. The -li option tells TDUMP to display a short form of "impdef" records when dumping import libraries. You can also specify a search string using the following syntax:
  109.  
  110.     -li=<string>
  111.  
  112. For example, the command
  113.  
  114.     TDUMP -li=codeptr import.lib
  115.  
  116. results in the following output:
  117.  
  118.     Impdef:(ord) KERNAL.0336=ISBADCODEPTR
  119.  
  120. This output shows that the function is exported by ordinal, whose ordinal value is 336 (decimal). In addition, the output displays the module and function name.
  121.  
  122. If you give the command
  123.  
  124.     TDUMP -li=walk import32.lib
  125.  
  126. TDUMP displays:
  127.  
  128.     Impdef:(name) KERNEL32.????=HEAPWALK
  129.  
  130. This shows the output of a function exported by name.
  131.  
  132. The ûle option tells TDUMP to display a short form of the ôexpdefö records when dumping OBJ files. You can also specify a search string using the following syntax:
  133.  
  134.     -le=<string>
  135.  
  136. The -m option
  137.  
  138. The -m option leaves C++ names occurring in object files, executable files, and Turbo Debugger symbolic information files in "mangled" format. This option is helpful in determining how the C++ compiler "mangles" a given function name and its arguments.
  139.  
  140. The -o, -oc, -oi, and -ox options
  141.  
  142. -o displays the file as an object (.OBJ) file. An object file display contains descriptions of the command records that pass commands and data to the linker, telling it how to create an .EXE file. The display format shows each record and its associated data on a record-by-record basis.
  143.  
  144. -oc causes TDUMP to perform a cyclic redundancy test (CRC) on each encountered record. The display differs from the -o display only if an erroneous CRC check is encountered (the TDUMP CRC value differs from the record's CRC byte).
  145.  
  146. -oi<id> includes only specified record types in the object module dump. Replace <id> with the name of the record to be displayed. For instance,
  147.  
  148.     TDUMP -oiPUBDEF MYMODULE.OBJ
  149.  
  150. produces an object module display for MYMODULE.OBJ that displays only the PUBDEF records.
  151.  
  152. -ox<id> excludes designated record types from the object module dump. Replace <id> with the record name not to be displayed. For instance,
  153.  
  154.     TDUMP -oxPUBDEF MYMODULE.OBJ
  155.  
  156. produces an object module display for MYMODULE.OBJ that excludes the PUBDEF records.
  157.  
  158. The -ox and -oi options are helpful in finding errors that occur during linking. By examining the spelling and case of the EXTDEF symbol and the PUBDEF symbol, you can resolve many linking problems. For instance, if you receive an "unresolved external" message from the linker, use TDUMP -oiEXTDEF to display the external definitions occurring in the module causing the error. Then, use TDUMP -oiPUBDEF on the module containing the public symbol the linker could not match.
  159.  
  160. Another use for the -oi switch is to check the names and sizes of the segments generated in a particular module. For instance,
  161.  
  162.     TDUMP -oiSEGDEF MYMODULE.OBJ
  163.  
  164. displays the names, attributes, and sizes of all of the segments in MYMODULE.
  165.  
  166. Note:    To get a list of record types for -oi and -ox, use the command-line options -oi? and -ox?.
  167.  
  168. The -r option
  169.  
  170. The -r option causes TDUMP to display raw data.
  171.  
  172. The -R option
  173.  
  174. The -R option causes TDUMP to dump relocation tables from 32-bit PE (Win32) format images. The default is to suppress these dumps.
  175.  
  176. The ûs and ûsu options
  177.  
  178. The ûs option tells TDUMP to display strings. By default ûs displays all strings in a given file. You can specify a string, or part of a string, using the following syntax:
  179.  
  180.     -s=<string>
  181.  
  182. For example, the command
  183.  
  184.     TDUMP -s=black GoGame.exe
  185.  
  186. results in the following output of all strings containing æblackÆ:
  187.     56840: IDI_BLACK
  188.     81965: Capture Black
  189.     85038: black.bmp
  190. The optional string argument is case insensitive. To specify several words of a string, use quotes. For example:
  191.  
  192.     TDUMP -s=ögame of goö GoGame.exe
  193.  
  194. The ûsu option is used in the same manner, with an optional string argument, and tells TDUMP to display Unix-style strings, meaning with no offset. For example, the command:
  195.  
  196.     TDUMP -su=black GoGame.exe
  197.  
  198. results in the following output:
  199.     IDI_BLACK
  200.     Capture Black
  201.     black.bmp
  202. For the -s[xx] switch, xx can be:
  203.     # - minimum string length to look for (default: 4)
  204.     b# - Beginning file offset (-b# is the same as -sb#)
  205.     e# - Ending file offset
  206.     f - Format (wrap) long strings
  207.     s - Search string with case sensitivity (default: no)
  208.     u - unix format: no offset (or decimal offsets, -h for hex)
  209.  
  210.     =x - x = search string
  211.  
  212. The -um option
  213.  
  214. The -um option is used to display mangled names as unmangled. You do not need to reformat the text to edit out only the manged names before using this option. You can pass output that has manged names anywhere in the text, and only the manged names will be affected.
  215.  
  216. The -v option
  217.  
  218. The -v option is used for verbose display. If used with an .OBJ or .LIB file, TDUMP produces a hexadecimal dump of the record's contents without any comments about the records.
  219.  
  220. If you use TDUMP on a Turbo Debugger symbol table, it displays the information tables in the order in which it encounters them. TDUMP doesn't combine information from several tables to give a more meaningful display on a per-module basis.
  221.  
  222. The -x option
  223.  
  224. The -x<id> option is used to specify the debug table(s) to exclude
  225.  
  226.  
  227. If you use TDUMP on a Turbo Debugger symbol table, it displays the information
  228. tables in the order in which it encounters them. TDUMP doesn't combine information
  229. from several tables to give a more meaningful display on a per-module basis.
  230.  
  231.  
  232. ===================================================================
  233. 2.  Understanding "Undefined Symbol" Error Messages
  234. ===================================================================
  235. One of the most common error messages seen by developers using a C or
  236. C++ compiler is "undefined symbol." This document provides a general
  237. description of what causes undefined symbol error messages, as well as
  238. instructions on solving specific undefined symbol errors.
  239.  
  240. The following error message are treated in order:
  241.   UNDEFINED SYMBOL AT COMPILE TIME
  242.   UNDEFINED SYMBOL AT LINK TIME
  243.   OTHER UNDEFINED SYMBOL ERRORS
  244.   o  UNDEFINED SYMBOL WHEN LINKING A BORLAND EXAMPLE
  245.   o  UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE
  246.   o  UNDEFINED SYMBOL LINKING C/C++ AND ASSEMBLY MODULES
  247.   o  UNDEFINED SYMBOL LINKING C++ WITH C OR ASSEMBLY MODULES
  248.   o  UNDEFINED SYMBOL: '_main' IN MODULE C0.ASM
  249.   o  UNDEFINED SYMBOL LINKING A DLL
  250.   o  UNDEFINED SYMBOL: A PSEUDO REGISTER (ie. _AX)
  251.   o  UNDEFINED SYMBOL: 'FIWRQQ'
  252.   o  UNDEFINED SYMBOL: AN IOSTREAM CLASS MEMBER
  253.   o  UNDEFINED SYMBOL: 'abort()'
  254.   o  UNDEFINED SYMBOL: '_exitclean()'
  255.   o  UNDEFINED SYMBOL: LLSH or SCOPY or FMUL or FDIV
  256.   o  UNDEFINED SYMBOL: STATIC POINTER TO A CLASS MEMBER FUNCTION
  257.   o  UNDEFINED SYMBOL: '_WSPRINTF'
  258.   o  UNDEFINED SYMBOL: 'fidrqq'
  259.   o  UNDEFINED SYMBOL IN WINDOWS.H
  260.   o  UNDEFINED SYMBOL USING TCLASDLL.LIB
  261.   o  UNDEFINED SYMBOL USING SELECTORS PROVIDED BY WINDOWS
  262.   o  UNDEFINED SYMBOL: 'ChangeSelector'
  263.   o  UNDEFINED SYMBOLS USING THE OBJECTWINDOWS LIBRARY (OWL)
  264.   o  UNDEFINED SYMBOL: 'Object::new(unsigned int)'
  265.   GETTING A CLOSER LOOK
  266.   o  USING TDUMP TO RESOLVE UNDEFINED SYMBOLS
  267.   o  USING IMPDEF TO RESOLVE UNDEFINED SYMBOLS IN A DLL
  268.  
  269.  
  270. UNDEFINED SYMBOL AT COMPILE TIME
  271. --------------------------------
  272. An undefined symbol at compile time indicates that the named
  273. identifier was used in the named source file, but had no definition in
  274. the source file. This is usually caused by a misspelled identifier
  275. name, or missing declaration of the identifier used.
  276.  
  277. EXAMPLE 1:
  278.     int main(void)
  279.     {
  280.         test = 1;
  281.         return 0;
  282.     }
  283.  
  284. The code shown in Example 1 generates an undefined symbol error if the
  285. variable "test" was not declared in either an included header file or
  286. in the actual source file itself.
  287.  
  288. EXAMPLE 2:
  289.     int main(void)
  290.     {
  291.         int test;
  292.         Test = 1;
  293.         return 0;
  294.     }
  295.  
  296. The code shown in Example 2 causes an undefined symbol error message
  297. to be displayed because the variable "Test" was not spelled as it was
  298. declared. Remember that C and C++ are case-sensitive languages.
  299.  
  300.  
  301. UNDEFINED SYMBOL AT LINK TIME
  302. -----------------------------
  303. When linking multi-file projects, the linker must resolve all
  304. references to functions and global variables shared between modules.
  305. When these references cannot be resolved, the linker generates
  306. an "undefined symbol" error message. This means that after searching
  307. all of the object files and libraries which are included in the link,
  308. the linker was unable to find a declaration for an identifier you
  309. used. This can be caused by:
  310.  
  311.   o  Forgetting to include a needed object module or library in
  312.      your link (project file, response file, or command line).
  313.  
  314.   o  Misspelling the name of the undefined symbol either where it
  315.      was used or where it was declared.
  316.  
  317.   o  Accidentally declaring a global variable as "extern."
  318.  
  319.   o  Forgetting to use extern "C" to disable name mangling when you're
  320.      mixing C++ with C or Assembly modules. See the specific entry on
  321.      this subject elsewhere in this document or consult the
  322.      HELPME!.DOC file included with the product.
  323.  
  324.   o  Turning OFF Generate Underbars in one of the modules you're
  325.      linking.
  326.  
  327. If all else fails, use TDUMP to dump both object modules and note any
  328. difference between the symbols used. This will usually give enough
  329. insight to resolve the problem. For more information on using TDUMP to
  330. resolve undefined symbol errors, see the "Getting a Closer
  331. Look "section in this document.
  332.  
  333.  
  334. OTHER UNDEFINED SYMBOL ERRORS
  335. ------------------------------
  336. The following list provides solutions to some of the more common
  337. causes of undefined symbol errors:
  338.  
  339.   o  UNDEFINED SYMBOL WHEN LINKING A BORLAND EXAMPLE
  340.      Almost all of Borland's examples come with project files. You
  341.      must use the project file when building the example to ensure
  342.      that all necessary modules are linked and all the necessary
  343.      settings are defined.
  344.  
  345.   o  UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE
  346.      The TLINK command line must have the libraries in the following
  347.      order ( GRAPHICS.LIB + <user libs> + EMU.LIB + MATH (S,T,C,M,L -
  348.      for model) + C (S,T,C,M,L - for model)
  349.  
  350.   o  UNDEFINED SYMBOL LINKING C/C++ AND ASSEMBLY MODULES
  351.      There are several sources of undefined symbol errors when trying
  352.      to link assembly with C or C++ modules:
  353.  
  354.        o  Turbo Assembler generates all upper-case symbols unless you
  355.           specify /ml or /mx on the assembly command line. Since C
  356.           modules are, by default, case sensitive, failing to do this
  357.           will result in undefined symbols for all symbols that are
  358.           not completely upper case in the C module(s).
  359.  
  360.        o  The symbols in the assembly file being referenced from a C
  361.           module must be declared using a PUBLIC directive. TLINK does
  362.           not consider symbols which are not declared PUBLIC when it
  363.           attempts to resolve an undefined symbol.
  364.  
  365.        o  All symbols in the assembly module that are referenced in
  366.           the C module must be prototyped/declared as extern in the C
  367.           module -- the compiler generates undefined symbol errors for
  368.           all symbols not declared in this manner. In addition, all
  369.           symbols in the assembly module that are referenced from a C
  370.           module must have an underscore prefix. This naming
  371.           convention must be used in the assembly module. You can
  372.           either do this explicitly (_symbol) or you can use:
  373.  
  374.             .model <memory model used>, C
  375.  
  376.           to specify this implicitly for all symbols.
  377.  
  378.           IMPORTANT NOTE: If you put underscores in front of your
  379.           assembly routines and also use the .model (memory model)
  380.           C directive, the public symbol will be generated with two
  381.           underscores; consequently an undefined symbol error is
  382.           generated.
  383.  
  384.           If all else fails, TDUMP both object modules and note any
  385.           difference between symbols. This will usually give enough
  386.           insight to resolve the problem. For more information on
  387.           using TDUMP to resolve undefined symbol errors see the
  388.           "Getting a Closer Look" section in this document.
  389.  
  390.   o  UNDEFINED SYMBOL LINKING C++ WITH C OR ASSEMBLY MODULES
  391.      C++ is a strongly typed language. In order to support type-safe
  392.      linkage (as well as function overloading), Borland C++ must
  393.      attach information to the symbols generated for function names
  394.      and variables. When this is done, the symbol will no longer match
  395.      the standard C style function name. In order to link correctly
  396.      with C or assembly modules, the compiler must be notified that
  397.      the symbol is to be in the standard C style (non-encoded) rather
  398.      than employing C++ name-mangling (encoded). This is done by
  399.      prototyping the function as type extern "C". Here is a quick
  400.      example:
  401.  
  402.        extern "C" int normal_c_func( float, int, char );
  403.  
  404.      For an additional example, you may want to look at the header
  405.      files which came with the product. One such header file is
  406.      stdio.h.
  407.  
  408.   o  UNDEFINED SYMBOL: '_main' IN MODULE C0.ASM
  409.      Every DOS C program must contain a function called main(). This
  410.      is the first function executed in your program. The function name
  411.      must be all in lower case. If your program does not have one,
  412.      create one. If you are using multiple source files, the file that
  413.      contains the function main() must be one of the files listed in
  414.      the project.
  415.  
  416.      Note that an underscore character '_' is prepended to all
  417.      external Borland C++ symbols.
  418.  
  419.      In addition to an absent, misspelled or mis-cased symbol main,
  420.      there are two additional common causes:
  421.  
  422.        o  The "generate underbars" option is disabled.
  423.  
  424.        o  The Pascal calling Convention rather than the C calling
  425.           convention is selected.
  426.  
  427.  
  428.   o  UNDEFINED SYMBOL LINKING A DLL
  429.      It is relatively simple to link a DLL to your source:
  430.  
  431.        1)  Create a .LIB from the .DLL using Borland's implib utility.
  432.  
  433.        2)  Include the .LIB in your project if you're using the IDE or
  434.            in your TLINK command if you're using the command-line
  435.            compiler or linker.
  436.  
  437.        3)  Turn case sensitive link ON.
  438.  
  439.        4)  Turn case sensitive exports ON.
  440.  
  441.      The issues of linking C++ with C, assembly, or any other language
  442.      still apply. See the sections on linking C++, C, and assembly in
  443.      this document.
  444.  
  445.      If the link still fails, the techniques in the section "Getting A
  446.      Closer Look" should help you resolve the problem.
  447.  
  448.   o  UNDEFINED SYMBOL: A PSEUDO REGISTER (i.e. _AX)
  449.      Pseudo registers are only allowed in the Borland C++ and ANSI
  450.      modes of the compiler. You can change this setting in the
  451.      Options | Compiler | Source menu.
  452.  
  453.   o  UNDEFINED SYMBOL: 'FIWRQQ'
  454.      Your program uses floating point routines directly (or
  455.      indirectly) and you have NONE selected for floating point. Or,
  456.      you are using TLINK and have forgotten to include EMU.LIB or
  457.      FP87.LIB on the command line.
  458.  
  459.   o  UNDEFINED SYMBOL: AN IOSTREAM CLASS MEMBER
  460.      If you are using the Integrated Development Environment, simply
  461.      turn off Options | Compiler | Code Generation | Unsigned
  462.      Characters.
  463.  
  464.      If you are using the command-line compiler, simply remove the
  465.      '-K' option.
  466.  
  467.   o  UNDEFINED SYMBOL: 'abort()'
  468.      The sole purpose of abort is to print the error message
  469.  
  470.        "Abnormal Program Termination"
  471.  
  472.      and exit the program with an error code of 3. This function is
  473.      located in the startup code C0.ASM. Linker errors indicating that
  474.      abort() is an undefined symbol are only possible if the standard
  475.      startup code is not being linked into a project. Although this is
  476.      not a common C/C++ development practice, it is to be expected
  477.      when linking in code written other languages such Microsoft
  478.      Fortran, Clipper, or in cases where embedded systems are being
  479.      developed. To resolve the undefined symbol, extract the abort()
  480.      function from the startup code and make a separate object out of
  481.      it to be linked into the project.
  482.  
  483.   o  UNDEFINED SYMBOL: '_exitclean()'
  484.      There is a function called _exitclean which is new to Turbo C++.
  485.      Users moving from Turbo C 2.0 to Turbo C++ may encounter
  486.      _exitclean() as an undefined symbol at link time. _exitclean() is
  487.      defined in the Turbo C++ startup code. Users creating embedded
  488.      system (ROMable code), who do not use the standard Turbo C++
  489.      startup code, are likely to encounter _exitclean() as an
  490.      undefined symbol. These users can strip the function from the
  491.      C0.ASM file and create a separate .OBJ file which can be linked.
  492.      Another option would be to purchase the Borland C++ RTL source and make
  493.      the necessary adjustments.
  494.  
  495.   o  UNDEFINED SYMBOL: LLSH or SCOPY or FMUL or FDIV
  496.      The helper functions have changed their names from Turbo C 2.0 to
  497.      Turbo C++. This can lead to many undefined symbol issues.
  498.  
  499.      When LLSH or SCOPY or FMUL or FDIV (note no underscores here)
  500.      appear as undefined symbols at link time, it is likely that an
  501.      object module or library has code generated a call to some helper
  502.      function from the Turbo C 2.0 libraries. The solution is to
  503.      simply recompile all objects from source. You can do this by
  504.      choosing Compile | BuildAll from the menu in the IDE.
  505.  
  506.   o  UNDEFINED SYMBOL: STATIC POINTER TO A CLASS MEMBER FUNCTION
  507.      Any static member of a class must be initialized--if not that
  508.      static member generates an undefined symbol error. The following
  509.      is an example of how to initialize a static pointer to class
  510.      member function of a class is initialized:
  511.  
  512.      // When testing static member initialization, you must
  513.      // declare an instance of the class in a main function;
  514.      // otherwise, the linker has no reference which it must
  515.      // try to resolve, and the undefined symbol error will
  516.      // not be seen - thus you won't know that your
  517.      // initialization was in error.
  518.  
  519.      #include <iostream.h>
  520.  
  521.      // used to allow global initialization of static member pointer
  522.      typedef void (*fptr)();
  523.  
  524.      // declare class containing static members
  525.      class First
  526.      {
  527.        public:
  528.           static fptr statptr;
  529.      };
  530.  
  531.      // initialize static members of class First
  532.      fptr First::statptr = NULL;
  533.  
  534.      int main(void) {
  535.           First fVar;
  536.  
  537.           if (fVar.statptr == NULL)
  538.                cout << "fVar.statptr is NULL: " <<
  539.                fVar.statptr << endl;
  540.  
  541.           return 0;
  542.      } // end of main()
  543.  
  544.   o  UNDEFINED SYMBOL: '_WSPRINTF'
  545.      Turn off the "Case-sensitive exports" and "Case-sensitive link"
  546.      options. If you are using the command linker, don't use the /c
  547.      switch. If you are invoking the linker from the BCC(x) command
  548.      line, use the -lc- switch. If you are using the IDE, go to the
  549.      linker options dialog box and turn off the case sensitivity
  550.      switch.
  551.  
  552.   o  UNDEFINED SYMBOL: 'fidrqq'
  553.      You will get an undefined symbol fidrqq when using the Integrated
  554.      Development Environment if you have the Options | Compiler | Code
  555.      Generation | More | Floating Point Option set to NONE and you are
  556.      using floating point arithmetic in your program. In order to best
  557.      solve this problem you must set the IDE option for Floating Point
  558.      to either the emulation choice or to the 80x87 choice. Note that
  559.      if you choose an 80x87 setting the application generated by the
  560.      compiler will require an 80x87 chip to be present at run-time.
  561.      Use this setting only when truly appropriate.
  562.  
  563.   o  UNDEFINED SYMBOL IN WINDOWS.H
  564.      Make sure you are using the windows.h file that came with Borland
  565.      C++, NOT the windows.h that came with the Microsoft Windows SDK.
  566.      If you include the Microsoft windows.h file you will get many
  567.      undefined symbols including WINMAIN in caps and translatemessage
  568.      in lower case. Use our windows.h file instead of Microsoft's when
  569.      you are using our compiler.
  570.  
  571.   o  UNDEFINED SYMBOL USING TCLASDLL.LIB
  572.      To use the DLL version of the container class library you must do
  573.      ALL of the following:
  574.  
  575.        o  Use the large memory model
  576.  
  577.        o  Use Smart Callbacks
  578.  
  579.        o  Turn case sensitive link ON
  580.  
  581.        o  Turn case sensitive exports ON
  582.  
  583.        o  Use the DLL version of the RTL
  584.  
  585.        o  Define _CLASSDLL
  586.  
  587.   o  UNDEFINED SYMBOL USING SELECTORS PROVIDED BY WINDOWS
  588.      If you are using _C000h or other selectors provided by Windows
  589.      and they are coming up as undefined symbols, perhaps you are
  590.      compiling in C++ mode and forgot to extern "C" them.
  591.  
  592.      Programming in C:
  593.        extern WORD _C000h
  594.  
  595.      Programming in C++:
  596.        extern "C" WORD _C000h
  597.  
  598.   o  UNDEFINED SYMBOL: 'ChangeSelector'
  599.      The Windows API function ChangeSelector() has the wrong name in
  600.      KERNEL.EXE for Windows 3.0, and therefore in IMPORT.LIB. The name
  601.      given to this function (and this is NOT a joke) is 
  602.      PrestoChangoSelector().
  603.  
  604.      Use PrestoChangoSelector() in your program in place of
  605.      ChangeSelector() and all will be well.
  606.  
  607.   o  UNDEFINED SYMBOLS USING THE OBJECTWINDOWS LIBRARY (OWL)
  608.      If you get any of the following the undefined symbols:
  609.  
  610.        TApplication(unsigned char far *, unsigned int, unsigned int,
  611.            unsigned char far *, int )
  612.  
  613.        and
  614.  
  615.        TWindow::TWindow(TWindowsObject near *, unsigned char far *,
  616.            TModule near *)
  617.  
  618.        and are using the DLL versions of OWL and the Class Library,
  619.        you must define _CLASSDLL in Options | Compiler | Code
  620.        Generation | defines combo box.
  621.  
  622.        It could be because you have forced unsigned characters. The
  623.        functions in the .lib take signed characters and thus if you
  624.        compile to use unsigned characters, the symbols will not match.
  625.  
  626.        Using the Integrated Development Environment be sure to turn
  627.        off Options | Compiler | Code Generation | Unsigned Characters.
  628.  
  629.        If you are using the command line compiler be sure to remove
  630.        the -K option to solve this problem.
  631.  
  632.   o  UNDEFINED SYMBOL: 'Object::new(unsigned int)'
  633.      You forgot to link with the TCLASDLL.LIB file where it is
  634.      defined!
  635.  
  636.      Basically the problem is that you are mixing both STATIC and
  637.      DYNAMIC LINK libraries into the application. You must use only
  638.      one or the other. If you are working in the IDE, change the
  639.      LINKER options section for libraries.
  640.  
  641.      If you are using the dynamic link library, remember to set
  642.      _CLASSDLL and Build All.
  643.  
  644.      If you are using the command line compiler and linker, just be
  645.      sure to specify the correct set of library files. For specific
  646.      information on the "correct set of library files" please see the
  647.      documentation included with the product as library names tend to
  648.      change from version to version.
  649.  
  650.  
  651. GETTING A CLOSER LOOK
  652. ---------------------
  653. Borland provides tools that you can use to determine exactly what the
  654. linker is seeing when it is trying to match symbols: TDUMP and IMPDEF.
  655. This section provides some simple techniques for using these utilities
  656. to resolve undefined symbol errors.
  657.  
  658.   o  USING TDUMP TO RESOLVE UNDEFINED SYMBOLS
  659.      TDUMP can be used to list the symbols in a .OBJ or a static .LIB
  660.      that the linker is having trouble matching.
  661.  
  662.      First, TDUMP the module that is trying to reference the symbol.
  663.      For example, if main.cpp is trying to access a function, myfunc()
  664.      in myfuncs.cpp and is getting "Undefined symbol myfunc() in
  665.      module main.cpp",
  666.  
  667.          tdump -m -oiEXTDEF main.obj > main.ext
  668.  
  669.      Then, TDUMP the module in which the symbol is defined.
  670.  
  671.          tdump -m -oiPUBDEF myfuncs.obj > myfunc.pub
  672.  
  673.      Using a text editor find the symbol associated with the error in
  674.      each file. If they are not the same, then you have verified that
  675.      the linker is correct in generating the error. You must check
  676.      your code and verify that the compiler is seeing the same
  677.      declaration for the symbol when each module is being compiled.
  678.  
  679.      You can use TDUMP to look at a static .LIB file the same way you
  680.      look at an .OBJ. file.
  681.  
  682.          tdump -m -oiPUBDEF mystatic.lib > mystatic.pub
  683.  
  684.      To use TDUMP with an implib,
  685.  
  686.          tdump -m -oiTHEADR mydll.lib > mydll.pub
  687.  
  688.      You can also use IMPDEF to view the symbols exported by a DLL.
  689.  
  690.  
  691.   o  USING IMPDEF TO RESOLVE UNDEFINED SYMBOLS IN A DLL
  692.      If you are trying to link a Borland generated DLL with another
  693.      language or product and are getting undefined symbol errors, you
  694.      should verify that the names or the ordinals that are being
  695.      exported by the DLL are the same as your application expects.
  696.  
  697.      This can be done by generating a .DEF file with the utility
  698.      IMPDEF. For example, to create a .DEF file for MY.DLL,
  699.  
  700.         impdef my.def my.dll
  701.  
  702.      The .DEF file will have the exported symbol name and its ordinal
  703.      number. Remember that C++ mangles names. Your application must
  704.      expect the mangled symbol name to call the function in the DLL
  705.      properly. This can be a problem if the application automatically
  706.      uppercases the symbol name before trying to call the function. If
  707.      this is so, you must change the declaration of the function and
  708.      re-build your DLL.
  709.  
  710.  
  711. ===================================================================
  712. 3.  Resolving Undefined Symbol linker messages
  713. ===================================================================
  714. This section provides an overview of the Linking process and helps to
  715. identify causes of 'unresolved external symbols'.
  716.  
  717. The code for printf() is in a module in the run time library. When you
  718. call printf() in a C/C++ module, the compiler creates a record
  719. (referred to as EXTDEF - EXTernal DEFinition) that indicates the call
  720. to an external function. The linker then looks at that OBJ, along with
  721. all the other modules and libraries specified and attempts to find
  722. another module (.OBJ or .LIB) which defines/provides the
  723. symbolprintf().
  724.  
  725. If the linker cannot resolve the call to printf(), the linker
  726. generates an error indicating that printf() is an undefined symbol.
  727. The error message, however, is very often not the result of leaving
  728. out the module containing the symbol being looked for, but rather a
  729. discrepancy between the name used by the caller (the C/C++ module
  730. calling printf() in the case mentioned above) and the supplier (the
  731. LIBRARY containing the code to printf() ).
  732.  
  733. The *real* name of any symbol is almost always different from the
  734. name/identifier used by the programmer. For example, the *real* name
  735. (by *real* name we mean the identifier used/generated by the tools) of
  736. strcpy() is: '_strcpy()'. The *real* name of a symbol depends on the
  737. various settings and options. The relevant settings are list below:
  738.  
  739.   Calling Conventions:
  740.         > cdecl
  741.         > pascal
  742.         > fastcall
  743.  
  744.   Compiler Settings:
  745.         > generate underbars
  746.         > unsigned chars    ( C++ only )
  747.  
  748.   Optimizations:
  749.         > Object Data Calling   ( C++ only )
  750.  
  751.   Virtual Table:
  752.         > Far Virtual Tables
  753.  
  754.   Language used:
  755.         > C
  756.         > C++
  757.         > Assembly
  758.  
  759. Furthermore there are two options which affect how the linker attempts
  760. to match symbols:
  761.  
  762.         > Case sensitive link
  763.         > Case sensitive exports ( Windows only )
  764.  
  765. The following is a discussion of how the above mentioned options
  766. affect the *real* name of symbols, hence the resolution of symbols.
  767.  
  768.  
  769. Calling Conventions
  770. -------------------
  771. Borland and Turbo C++ both allow you to specify the default calling
  772. convention. This default can be overridden by using the
  773. 'pascal', '_fastcall' or 'cdecl' keywords. Whether set globally or on
  774. individual function instances, the calling convention affects the name
  775. of functions. By default, when the compiler encounters a function
  776. declared as,
  777.  
  778.     int Foo( int );    // or: int cdecl Foo( int );
  779.  
  780. the name generated is _Foo; that is, the resulting name has the same
  781. case but is preceded with a leading underscore. The generation of the
  782. underscore is the default behavior and is necessary when you link to
  783. the run time libraries. There is no 'printf()' symbol in the RTL
  784. (!),but there is a '_printf()'.
  785.  
  786. While the C calling convention implies 'Case Sensitivity' and
  787. 'Generation of Underbars', Borland/Turbo C++ provides separate
  788. settings for the generation of underbars and the calling convention
  789. Generation of Underbars can be controlled from the Options | Compiler|
  790. Advanced Code Generation Dialog, or the -u option from the command
  791. line ( -u- would turn it off, it is on by default). The 'Calling
  792. Convention' can be modified via the Options | Compiler |
  793. Entry/ExitCode Dialog.
  794.  
  795. If our function 'Foo' is declared with the pascal modifier, for
  796. example:
  797.  
  798.     int pascal Foo( int );
  799.  
  800. (or if the default 'Calling Convention' is set to 'PASCAL') the
  801. resulting name will be FOO--that is, all upper-case with no
  802. underscore. The '_fastcall' modifier is similar to 'cdecl' in regards
  803. to Case Sensitivity but the underscore character is replaced with '@'.
  804. Hence:
  805.  
  806.     int _fastcall Foo( int );
  807.  
  808. will result in the '@Foo' symbol.
  809.  
  810. Therefore, mismatching the calling conventions might result in
  811. 'Undefined Symbols.' Watch for clues in the undefined symbol name
  812. provided in the Linker error messages (look at the Case Sensitivity
  813. and any leading characters) to spot cases of incorrect settings in the
  814. 'Calling Convention' and/or 'Generation of Underbars'.
  815.  
  816.  
  817. NAME MANGLING:
  818. --------------
  819. The C++ language uses yet another naming convention as part of its
  820. implementation of 'type safe linkage.' Imagine a function myfunc()
  821. which take two longs [void myfunc( long, long );]. What if someone has
  822. it incorrectly prototyped in a calling module as taking two floats,
  823. for example void myfunc( float, float );. The results of such a call
  824. will be unpredictable. When using the C language, the linker would
  825. resolve such a call since the symbol the compiler uses to call the
  826. function taking two floats will be '_myfunc()', and the name the
  827. compiler used in the module which implements the function taking two
  828. longs is also '_myfunc()'.
  829.  
  830. In C++, however, the name the compiler generates for a function is a
  831. 'mangled' name: it is 'encrypted' based on the parameters types the
  832. function expects. In the scenario described in the prior paragraph, the
  833. call to myfunc() will not be resolved since the compiler generates
  834. different names for 'void myfunc( float, float )' and 'void myfunc(
  835. long, long )'.
  836.  
  837. Because a C++ function's mangled real name depends on the types of its
  838. parameters, if unsigned chars is used as a compiler option, it changes
  839. the name of functions declared to take a char, or char *. Unsigned
  840. chars is off by default, it is turned on under the Options |Compiler |
  841. Code generation menu. Or by specifying the -K option with the command
  842. line compiler. Watch out for potential 'Undefined Symbol' messages
  843. caused by a mismatched of char vs. unsigned char.
  844.  
  845. The 'virtual mechanism' of C++ is implemented via a table commonly
  846. referred to as the Virtual Table or the VMT (Virtual Method Table).
  847. Various settings of the Compiler dictate whether the Table ends up in
  848. the Default Data Segment or in a Far Segment (namely Memory
  849. Model, '_export' and 'huge' class modifiers, Virtual Table Control
  850. Optionsetc). To further enforce 'type- safe-linkage', the
  851. Borland/Turbo C++ compilers include the 'distance' of the Virtual Table
  852. as part of its 'Name-Mangling' logic. This prevents the linker from
  853. resolving function calls which would crash at run-time because of
  854. mismatched 'Virtual Table Control' settings. In the same token,
  855. Borland provides the 'Object Data Calling convention' for improved
  856. efficiency of C++ code. Once again, the 'Name-mangling' algorithm also
  857. reflects the enabling of 'Object Data Calling'. This ensures that
  858. function calls involving mismatched 'Object Data Calling' convention
  859. between caller and callee will be caught at link time (instead of
  860. resulting in erratic run-time behavior).
  861.  
  862. To illustrate the effect of 'Virtual Table Control' and 'Object
  863. DataCalling,' let's create a simple class and look at the effects of
  864. the various settings on the resulting names:
  865.  
  866. class  Test
  867. {
  868.      public:
  869.          virtual int Process( void );
  870. };
  871.  
  872. int main( void )
  873. {
  874.      Test t;
  875.      return t.Process();
  876. }
  877.  
  878. The following table illustrates the effects of Compiler Settings on
  879. the *actual* name generated for the member function 'int
  880. Test::Process(void)'.
  881.  
  882.      +----------------------------------------------------------+
  883.      | Object Call. | Far V. Tbl. | Huge Md. |  [ REAL  NAME ]  |
  884.      |--------------+-------------+-----------------------------+
  885.      |      No      |     No      |  No     > @Test@Process$qv  |
  886.      |--------------+-------------+-----------------------------+
  887.      |      No      |     Yes     |  No     > @Test@0Process$qv |
  888.      |--------------+-------------+-----------------------------+
  889.      |      Yes     |     No      |  No     > @Test@1Process$qv |
  890.      |--------------+-------------+-----------------------------+
  891.      |     Yes      |     No      |  Yes    > @Test@2Process$qv |
  892.      +--------------+-------------+-----------------------------+
  893.  
  894. NOTE: Using the '_export' or 'huge' keyword when defining a class
  895.       results in Far Virtual Tables for the class.
  896.  
  897. 'Undefined Symbol Messages' caused by mismatching Virtual Table
  898. Controls or Object Data Calling conventions may be hard to identify; it
  899. is often useful to use TDUMP.EXE to find the actual names of the
  900. unresolved symbols (however, watch out of any '0', '1' or '2' following
  901. the '@ClassName@' portion of the real names).
  902.  
  903.  
  904. LANGUAGE USED
  905. -------------
  906. By default assemblers (including TASM) do not modify public
  907. names--they merely convert symbols to upper case. With TASM, the /mx
  908. option forces the assembler to treat public symbols with case
  909. sensitivity. Without /mx, a call to _myfunc from an assembly module
  910. looks like _MYFUNC to the linker (this causes undefined symbol errors
  911. when linking C and assembly).
  912.  
  913. NOTE: TASM has an extension which causes the automatic generation of
  914. underscores. See. .MODEL <model>, Language directives in the TASM
  915. User's Guide.
  916.  
  917. As previously mentioned in the section about 'Name Mangling,' the
  918. C++ language uses a different naming convention than does the C
  919. language. This can result in undefined symbols when calling C from C++
  920. (or vice-versa). C++ modules should use the 'extern "C"' syntax when
  921. interfacing with C modules (see the Name Mangling section of
  922. Programmer's Guide for the proper syntax).
  923.  
  924.  
  925. LINKER SETTINGS
  926. ---------------
  927. By default, the linker treats _myfunc and _MYFUNC as different
  928. symbols. However, you can control whether the linker pays attention to
  929. Case Sensitivity via the Options | Linker | Settings dialog (IDE), or
  930. the /c option with TLINK (/c: Enables Case Sensitivity [default],
  931. /c-turns the option off).
  932.  
  933. For example, if the option is disabled, a call to _myfunc could be
  934. resolved to _MYFUNC.
  935.  
  936. When creating a Windows application, not only can you link to 'static'
  937. modules (.OBJs or .LIBs which are a collection of .OBJs), but you can
  938. also link to dynamic libraries where the resolution of the call is
  939. completed by Windows at load time. Functions residing in DLLs and
  940. called from an .EXE are said to be imported. Functions that are coded
  941. in an .EXE or .DLL, and are called by either Windows, .EXEs, or .DLLs
  942. are said to be exported.
  943.  
  944. Functions are imported in two ways: by listing them in the IMPORTS
  945. section of the .DEF file, or by linking to an import library. Functions
  946. can be exported by two methods: by using the _export keyword in the
  947. source code or listing the functions in the EXPORTS section of the
  948. .DEF file.
  949.  
  950. Suppose your application calls the symbol _myfunc which is in a
  951. DLL. The linker can treat symbols coming from an import library, or
  952. IMPORTS section of the .DEF file with or without case sensitivity,
  953. (determined by the setting of case sensitive exports under the Options
  954. | Linker | Settings Dialog or /C option on the TLINK command line). If
  955. this setting is NOT enabled, then the Linker treats symbols in import
  956. libs or IMPORTS sections as all uppercase. It then considers upper
  957. case symbols during the link phase. At that point it is doing normal
  958. linking using the setting of the case sensitive link option. If we are
  959. importing both _myfunc and _MYFUNC without the /C option, the linker
  960. can only resolve the call to _MYFUNC.
  961.  
  962. If you are calling _myfunc (a cdecl function) and are performing a
  963. case sensitive link, but do not have case sensitivity on
  964. EXPORTS, _myfunc will show up as undefined.
  965.  
  966.      > Imported cdecl functions and C++ names will link when /c
  967.      > and /C are both enabled, or neither are enabled.
  968.  
  969. C++ names are always generated with lowercase letters. When importing
  970. or exporting C++ names, it's recommended that you use both the /c
  971. and/C options.
  972.  
  973. Now let's apply the above to some common scenarios and provide
  974. possible diagnostics and suggestions:
  975.  
  976.  
  977. PROBLEM:
  978.      All the functions in a 3rd party library are undefined!
  979.  
  980. SOLUTION:
  981.      3rd party libraries must be explicitly linked in. To explicitly
  982.      link to a 3rd party library from the IDE, open a project file and
  983.      insert the .LIB file into the project file. The project file also
  984.      needs to have all of your source code files listed in it. From
  985.      the command line, insert the .LIB on your command line to TLINK.
  986.  
  987.  
  988. PROBLEM:
  989.      All the functions in the RTL are undefined!
  990.  
  991. SOLUTION:
  992.      You need to link in Cx.LIB, where x is the memory model. A
  993.      feature of the IDE in Turbo C++ and Borland C++ v2.x is that if
  994.      you put a .LIB in the project file which starts out as Cx where x
  995.      is a memory model, the new library overrides the normal run time
  996.      library, and the latter will not be linked in (for example, if
  997.      you're using a library named CSERVE.LIB). Rename any such
  998.      libraries, then the normal Cx.LIB will automatically be linked
  999.      in. (Borland C++ 4.x has a dialog for specifying which Run Time
  1000.      Libraries should be linked in).
  1001.  
  1002.  
  1003. PROBLEM:
  1004.      When mixing C and C++ modules (.c and .cpp source) symbols are
  1005.      undefined.
  1006.  
  1007. SOLUTION:
  1008.      Because of name mangling (see above) the symbol the linker sees
  1009.      being called from a C++ module will not look like the symbol in
  1010.      the Cmodule. To turn name mangling off when prototyping
  1011.      functions:
  1012.  
  1013.      // SOURCE.CPP
  1014.  
  1015.      extern "C" {
  1016.           int Cfunc1( void );
  1017.           int Cfunc2( int  );
  1018.      }
  1019.  
  1020. NOTE:  You can also disable name-mangling for functions written in
  1021. C++ and called from C.
  1022.  
  1023. A C++ compile will happen if the source code has a .CPP extension, or
  1024. Options | Compiler | C++ options use C++ compiler is set to always.
  1025.  
  1026.  
  1027. PROBLEM:
  1028.      randomize and other macros are coming up as undefined symbols.
  1029.  
  1030. SOLUTION:
  1031.      Turn keywords to Borland C++. Since some macros are not ANSI
  1032.      compatible, the header files will not define them if compiled
  1033.      with ANSI or UNIX keywords on.
  1034.  
  1035.  
  1036. PROBLEM:
  1037.      min and max are coming up undefined.
  1038.  
  1039. SOLUTION:
  1040.      These macros are only included in a C compile, and will not be
  1041.      seen by the compiler if compiling in C++. In C, you must
  1042.      #include <stdlib.h> to use them.
  1043.  
  1044.  
  1045. PROBLEM:
  1046.      I cannot get my assembly modules to link with my C/C++ program.
  1047.  
  1048. SOLUTION:
  1049.      For C++, see above. Otherwise, the .ASM must be assembled with
  1050.      case sensitivity on public symbols (/mx for TASM). It must also
  1051.      match the C naming convention, which will have an underscore in
  1052.      front of the name. So given the following code in a C module,
  1053.  
  1054.      int myfunc( void );
  1055.  
  1056. you need to
  1057.  
  1058.      call _myfunc
  1059.  
  1060.      from the assembly module. (NOTE: TASM has extensions which will
  1061.      automatically generate underscores for you). Also, make sure the
  1062.      .OBJ which has the assembly code is listed in the project file,
  1063.      or on the tlink line.
  1064.  
  1065.  
  1066. PROBLEM:
  1067.      wsprintf is coming up undefined.
  1068.  
  1069. SOLUTION:
  1070.      In Borland C++ 2.0, to use wsprintf when case sensitive exports
  1071.      is on, you need to reverse a define in windows.h via the
  1072.      following:
  1073.  
  1074.      #ifdef   wsprintf
  1075.      #undef   wsprintf
  1076.  
  1077.      #define  wsprintf wsprintf
  1078.      extern   "C" int FAR cdecl wsprintf( LPSTR, LPSTR, ... );
  1079.      #endif
  1080.  
  1081.      To call wsprintf (or any cdecl imported function ) with case
  1082.      sensitive exports off, you need to match an upper case name. Thus
  1083.      windows.h #defines wsprintf to be WSPRINTF. wsprintf is one of the
  1084.      cdecl functions from windows, so the compiler will generate a
  1085.      lower case symbol for when calling it.
  1086.  
  1087.  
  1088. PROBLEM:
  1089.      FIWRQQ and FIDRQQ are undefined
  1090.  
  1091. SOLUTION:
  1092.      These symbols are in the EMU or FP87 library. You must link it
  1093.      in explicitly when using TLINK, or set the IDE to link it in under
  1094.      the Options | Compiler | Advanced Code Generation Floating point
  1095.      box.
  1096.  
  1097.  
  1098. PROBLEM:
  1099.      Warning attempt to export non-public symbol ...
  1100.  
  1101. SOLUTION:
  1102.      The exports section of the .DEF file has a symbol which does not
  1103.      match one the compiler generated in the source code. This happens
  1104.      if:
  1105.  
  1106.   o  The source was compile in C++ (the symbol name is mangled).
  1107.      Resolve by exporting with the _export keyword, compiling in C,
  1108.      or by declaring the function as extern "C".
  1109.  
  1110.   o  Case sensitive exports is ON, you are exporting a PASCAL
  1111.      function, and exporting it like: WndProc. Resolve by
  1112.      exporting as WNDPROC or by turning case sensitive exports off.
  1113.  
  1114.   o  You are exporting a cdecl function. If declared as
  1115.          int myfunc( void );
  1116.      export as _myfunc and turn case sensitive exports on (or
  1117.      just use the _export keyword).
  1118.  
  1119.      NOTE: When using the '_export' keyword, it must be used in
  1120.            the prototype of the function. For example:
  1121.                int FAR _export myfunc( int );
  1122.  
  1123.  
  1124. PROBLEM:
  1125.      C++ and DLL linking problems.
  1126.  
  1127. SOLUTION:
  1128.      Classes declared in the DLL need to be declared as the following:
  1129.  
  1130.      class _export A
  1131.      {
  1132.         ...
  1133.      };
  1134.  
  1135.      When defined in the EXE, the same must be prototyped as:
  1136.  
  1137.      class huge A
  1138.      {
  1139.           ...
  1140.      };
  1141.      // see User's Guide for more information
  1142.  
  1143.      Then link with /c and /C on (both case sensitive link and case
  1144.      sensitive exports ENABLED) when building BOTH the .DLL and the
  1145.      calling.EXE.
  1146.  
  1147.  
  1148. PROBLEM:
  1149.      OWL and undefined symbols.
  1150.  
  1151. SOLUTION:
  1152.      If you're linking to the static libraries:
  1153.           - with BC 2.0, link in owlwx.lib, tclasswx.lib, and
  1154.             sallocwx.lib. (You don't need sallocwx.lib with BC
  1155.             v 3.x ).
  1156.  
  1157.           - do NOT define _CLASSDLL in the code generation
  1158.             dialog, or before including owl.h.
  1159.  
  1160.           - link with /c and /C. (from IDE, under linker
  1161.             options, case sensitive link and case sensitive
  1162.             exports).
  1163.  
  1164.           - Do NOT compile with -K or unsigned char's on. You
  1165.             will get several undefined symbols in this case.
  1166.  
  1167.      If you're linking to the OWL .DLL, DO define _CLASSDLL before
  1168.      including OWL.H, and use /c and /C linker options (both Case
  1169.      Sensitive Link and Case Sensitive Exports ENABLED).
  1170.  
  1171.  
  1172. PROBLEM:
  1173.      With an OWL application, wsprintf is undefined in module when
  1174.      linking to the static libraries.
  1175.  
  1176. SOLUTION:
  1177.      Link with /C (case sensitive exports ENABLED).
  1178.  
  1179.  
  1180. PROBLEM:
  1181.      _main is an undefined symbol.
  1182.  
  1183. SOLUTION:
  1184.      main is the entry point for every DOS C/C++ program. Make sure
  1185.      you write a function called main (all lowercase) in your program.
  1186.      If you have a project file loaded, make sure your source code
  1187.      file (.c or .cpp file) which has main in it is listed in the .prj
  1188.      file. Make sure generate underbars is turned on.
  1189.  
  1190.  
  1191. PROBLEM:
  1192.      iostream members, like << operator are undefined
  1193.  
  1194. SOLUTION:
  1195.      Turn options | compiler | code generation | unsigned chars off
  1196.      (do not use -K on the command line).
  1197.  
  1198.  
  1199. PROBLEM:
  1200.      Getting undefined symbols LLSH, SCOPY FMUL, FDIV, etc
  1201.  
  1202. SOLUTION:
  1203.      Many of the helper functions have changed names from Turbo C
  1204.      2.0 to Borland C++. This functions were called from Turbo C 2.0.
  1205.      The solution is to recompile any .OBJ or .LIB them with Borland
  1206.      C++.
  1207.  
  1208.  
  1209. SNOOPING AT THE REAL NAMES:
  1210. ---------------------------
  1211. An .OBJ file is a collection of records. When you call a function or
  1212. reference a symbol not defined in your module, the compiler generates
  1213. an external definition record in the OBJ. This external definition
  1214. record has the symbol which the linker must resolve. When you define a
  1215. function, or make storage for some data, the compiler generates a
  1216. public definition record for that module (unless you declared the item
  1217. as static, that makes it private to that module). One of the tasks of
  1218. the Linker is to match Public Definitions and External
  1219. Definitions(PUBDEFs and EXTDEFs).
  1220.  
  1221. To see the symbols the LINKER has to deal with, use TDUMP.EXE provided
  1222. with the Borland C++ package. For example:
  1223.  
  1224.     tdump -m -oiEXTDEF some.obj
  1225.  
  1226. The above shows all the EXTDEF (external definition) records in an .OBJ
  1227. file. Be sure to add the -m option when coding in C++.
  1228.  
  1229.     tdump -m -oiPUBDEF some.obj
  1230.  
  1231. The above will display all the PUBDEF (public definition) records.
  1232.  
  1233. Let's assume you've purchased a third party library and a symbol
  1234. provided the library is unresolved; the possible steps in
  1235. identifying the problem could include:
  1236.  
  1237.      - Create a Listing of symbols in the Library using TLIB. For
  1238.        example:
  1239.           TLIB NEWLIB.LIB, NEWLIB.LST
  1240.  
  1241.      - TDUMP the .OBJ file which was created from the .C/.CPP
  1242.        module calling the desired function.
  1243.           TDUMP  -m -oiEXTDEF MYCODE.OBJ MYCODE.LST
  1244.  
  1245.      - Attempt to find any discrepancies between the name in
  1246.        NEWLIB.LST and the one in MYCODE.LST and ascertain that
  1247.        the Library does indeed provide the desired function.
  1248.  
  1249. Windows Programmers will find the IMPDEF.EXE utility (in addition to
  1250. TDUMP and TLIB) a very useful tool to help identify unresolved symbols
  1251. when DLLs and/or Import Libraries are involved.
  1252.  
  1253.  
  1254. ===================================================================
  1255. 4.  Borland Open Architecture:  Name Mangling
  1256. ===================================================================
  1257. There are four basic forms of encoded names in Borland C++:
  1258.  
  1259. 1. @className@functionName$args
  1260.  
  1261. This encoding denotes a member function Name belonging to
  1262. class Name and having arguments args.
  1263.  
  1264. Class names are encoded directly. The following example shows a
  1265. className in an encoded name:
  1266.  
  1267.       @className@...
  1268.  
  1269. The class name may be followed by a single digit; the digit value
  1270. contains the following bits (these can be combined):
  1271.  
  1272.     0x01 : the class uses a far vtable
  1273.  
  1274.     0x02 : the class uses the -po calling convention
  1275.  
  1276.     0x04 : the class has an RTTI-compatible virtual table; this bit is
  1277.            only used when encoding the name of the virtual table for
  1278.            the class
  1279.  
  1280. The digit is encoded as an ASCII representation of the bit mask
  1281. value, with 1 subtracted (so that, for example, the class prefix for a
  1282. class 'myfunc' that uses far vtables would be '@myfunc@0').
  1283.  
  1284. See the next section on the encoding of function names and argument
  1285. types.
  1286.  
  1287. 2. @functionName$args
  1288.  
  1289. This form of encoding denotes a function functionName with arguments
  1290. args.
  1291.  
  1292. 3. @className@dataMember
  1293.  
  1294. This form of encoding denotes a static data member dataMember
  1295. belonging to class className. Names of classes and data members are
  1296. encoded directly. The following example shows a member myMember in
  1297. class myClass:
  1298.  
  1299.       @myClass@myMember
  1300.  
  1301. 4. @className@
  1302.  
  1303. This name denotes a virtual table for a class className. As mentioned
  1304. previously, class names are encoded directly.
  1305.  
  1306.  
  1307. Encoding of nested and template classes
  1308. ---------------------------------------
  1309. The following form encodes a name of a class lexically nested within
  1310. another class:
  1311.  
  1312.   @outer@inner@...
  1313.  
  1314. A template instance class encodes the name of the template class, along
  1315. with the actual template arguments, in the following way:
  1316.  
  1317.   %templateName$arg1$arg2 ..... $argn%
  1318.  
  1319. Each actual argument starts with a letter, specifying the kind of
  1320. argument it is:
  1321.  
  1322.   o  t type argument
  1323.  
  1324.   o  i nontype integral argument
  1325.  
  1326.   o  g nontype nonmember pointer argument
  1327.  
  1328.   o  m nontype member pointer argument
  1329.  
  1330. The first letter is followed by the encoded type of the argument. For
  1331. a type argument, this code also represents the argument's actual
  1332. value. For other kinds of arguments, the type code is followed by $and
  1333. the argument value, encoded as an ASCII number or symbol name. An
  1334. instance of template<class T, int size> whose name is
  1335. vector<long,100>is encoded as shown in the following example:
  1336.  
  1337.   %vector$tl$ii$100%
  1338.  
  1339.  
  1340. Encoding of function names
  1341. --------------------------
  1342. The encoded function Name might denote either a function name, a
  1343. function such as a function such as a constructor or destructor, an
  1344. overloaded operator, or a type conversion.
  1345.  
  1346.  
  1347. Ordinary functions
  1348. ------------------
  1349. Ordinary function names are encoded directly, as shown in the
  1350. following examples:
  1351.  
  1352.   foo(int) --> @foo$qi sna::foo(void) --> @sna@foo$qv
  1353.  
  1354. The string $qi denotes the integer argument of function myfunc();'$qv'
  1355. denotes no arguments in sna::myfunc.
  1356.  
  1357.  
  1358. Constructors, destructors, and overloaded operators
  1359. ---------------------------------------------------
  1360. The following information covers argument encoding in more
  1361. detail. Constructors, destructors, and overloaded operators encoded
  1362. with a $bcharacter sequence, followed by a character sequence from the
  1363. following table:
  1364.  
  1365.             Character        Meaning Sequence
  1366.             _________________________________
  1367.  
  1368.             ctr              constructor
  1369.             dtr              destructor
  1370.             add              +
  1371.             adr              &
  1372.             and              &
  1373.             arow             ->
  1374.             arwm             ->*
  1375.             asg              =
  1376.             call             ()
  1377.             cmp              ~
  1378.             coma             ,
  1379.             dec              --
  1380.             dele             delete
  1381.             div              /
  1382.             eql              ==
  1383.             geq              >=
  1384.             gtr              >
  1385.             inc              ++
  1386.             ind              *
  1387.             land             &&
  1388.             lor              ||
  1389.             leq              <=
  1390.             lsh              <<
  1391.             lss              <
  1392.             mod              %
  1393.             mul              *
  1394.             neq              !=
  1395.             new              new
  1396.             not              !
  1397.             or               |
  1398.             rand             &=
  1399.             rdiv             /=
  1400.             rlsh             <<=
  1401.             rmin             -=
  1402.             rmod             %=
  1403.             rmul             *=
  1404.             ror              |=
  1405.             rplu             +=
  1406.             rrsh             >>=
  1407.             rsh              >>
  1408.             rxor             ^=
  1409.             sub              -
  1410.             subs             []
  1411.             xor              ^
  1412.             nwa              new[]
  1413.             dla              delete []
  1414.             __________________________________
  1415.  
  1416. The following examples show how arguments are encoded with character
  1417. sequences, add, ctr, and dtr from the previous table:
  1418.  
  1419.   operator+(int)  -->     @$badd$qi plot::plot() --> @plot@$bctr$qv
  1420.   plot::~plot()   --> @plot@$bdtr$qv
  1421.  
  1422. The string $qv denotes no arguments in the plot constructor or
  1423. destructor.
  1424.  
  1425.  
  1426. Type conversions
  1427. ----------------
  1428. Encoding of type conversions accomplished with the $o character
  1429. sequence, followed by distinguishing return type of the conversion as
  1430. part of function name. The return type follows the rules for argument
  1431. encoding, explained later. The lack of arguments in one version is
  1432. made explicit in the mangling by adding $qv the end of the encoded
  1433. string.
  1434.  
  1435. Example:
  1436.  
  1437.   myfunc::operator int() --> @myfunc@$oi$qv myfunc::operator char *()
  1438.   -->     @myfunc@$opzc$qv
  1439.  
  1440. The i following $o in the first example denotes int; the pzc in the
  1441. second example denotes a near pointer to an unsigned char.
  1442.  
  1443.  
  1444. Encoding of arguments
  1445. ----------------------
  1446. The number and combinations of function arguments make argument
  1447. encoding the most complex aspect of name mangling.
  1448.  
  1449. Argument lists for functions begin with the characters $q. Type
  1450. qualifiers are then encoded as shown in the following table:
  1451.          _____________________________
  1452.  
  1453.           Character   Meaning Sequence
  1454.          _____________________________
  1455.  
  1456.            up          huge
  1457.            ur          _seg
  1458.            u           unsigned
  1459.            z           signed
  1460.            x           const
  1461.            w           volatile
  1462.            ____________________________
  1463.  
  1464. Encoding of built-in types follows that for applicable type
  1465. qualifiers, in accordance with the following table:
  1466.  
  1467.            ______________________________
  1468.  
  1469.              Character   Meaning Sequence
  1470.            ______________________________
  1471.  
  1472.              v           void
  1473.              c           char
  1474.              s           short
  1475.              i           int
  1476.              l           long
  1477.              f           float
  1478.              d           double
  1479.              g           long double
  1480.              e           ...
  1481.            ______________________________
  1482.  
  1483. Encoding of non-built-in types follows that for applicable type
  1484. qualifiers, in accordance with the following table:
  1485.  
  1486.          ______________________________
  1487.  
  1488.            Character   Meaning Sequence
  1489.          ______________________________
  1490.  
  1491.            <a digit>   (an enumeration or class name)
  1492.            p           near *
  1493.            r           near &
  1494.            m           far &
  1495.            n           far *
  1496.            a           array
  1497.            M           member pointer (followed by class and
  1498.                        base type)
  1499.            ______________________________
  1500.  
  1501. The appearance of one or more digits indicates that an enumeration or
  1502. class name follows; the value of the digit(s) denotes the length of
  1503. the name, as shown in the following examples:
  1504.  
  1505.   foo::myfunc(myClass near&)      is mangled as @foo@myfunc$qr7myClass
  1506.   foo::myfunc(anotherClass near&) is mangled as
  1507.   @foo@myfunc$qr12anotherClass
  1508.  
  1509. A character x or w may appear after p, r, m, or n to denote a constant
  1510. or volatile type qualifier, respectively. The character q appearing
  1511. after one of these characters denotes a function with arguments the
  1512. follow in the encoded name, up to the appearance of a $ character, and
  1513. finally a return type is encoded. The following example show how these
  1514. encoding rules are applied:
  1515.  
  1516.   @foo@myfunc$qpxzc      is mangled as foo::myfunc(const char near*)
  1517.   @func1$qxi is mangled as   func1(const int) @foo@myfunc$qpqii$i is
  1518.   mangled as foo:myfunc(int (near*)(int,int))
  1519.  
  1520. Array types are encoded as a, followed by a dimension encoded as an
  1521. ASCII decimal number and a $, and finally the element type, as shown
  1522. in the following example.
  1523.  
  1524.   myfunc( int (*x)[20] )    is mangled as @myfunc$qpa20$i
  1525.  
  1526. Encoded arguments are concatenated in the order of appearance in the
  1527. function call. The character t followed by an ASCII character encodes
  1528. the arguments when a number of identical non-builtin types are
  1529. function arguments. The ASCII character, ranging from ASCII 31H -
  1530. 39Hand 61H - 7FH (1 to 9 and a onward), denotes which argument type to
  1531. duplicate, as shown in the following example:
  1532.  
  1533.   @plot@func1$qdddiiilllpzctata is unmangled to plot::func1(double,
  1534.           double, double, int, int, int, long, long, long, char near*,
  1535.           char near*, char near*)
  1536.  
  1537. The two duplicate ta character sequences at the end of the encoded
  1538. name denote the tenth argument, encoded as pzc.
  1539.  
  1540. /*************************************************************************/
  1541.  
  1542.