TDUMP.EXE

De Wiki expérimental


1. TDUMP: l'utilitaire d'inspection de fichiers

TDUMP.EXE produit un vidage montrant la structure d'un fichier.

TDUMP divise un fichier de manière structurelle et utilise son extension pour déterminer le format d'affichage de sortie. TDUMP reconnaît de nombreux formats de fichier, tels que.EXE, .OBJ et .LIB. Si TDUMP ne reconnaît pas une extension, il produit un vidage hexadécimal du fichier. Vous pouvez contrôler le format de sortie en utilisant les options de la ligne de commande TDUMP au lancement du programme.

La capacité de TDUMP à visualiser la structure interne d'un fichier permet non seulement de voir le contenu d'un fichier, mais aussi de savoir comment il est construit. De plus, comme TDUMP vérifie que la structure d'un fichier correspond à son extension, vous pouvez aussi l'employer pour tester l'intégrité des fichiers.

TDUMP peut lire son entrée depuis stdin par redirection (en utilisant un symbole supérieur à >) ou par pipe (en utilisant une barre verticale |).


Syntaxe TDUMP

La syntaxe de TDUMP est:

 TDUMP [<options>] <Inputfile> [<Listfile>] [<options>]
  • <options> représente l'une des options TDUMP discutées dans le section suivante. Pour obtenir la liste des options de ligne de commande disponibles, tapez TDUMP, puis appuyez sur <Entrée> à l'invite DOS.
  • <Inputfile> est le fichier dont vous souhaitez afficher la structure (ou "déverser").
  • <Listfile> est un nom de fichier de sortie facultatif. Notez que vous pouvez utilisez également la commande de redirection DOS standard ">" pour créer un fichier de sortie.

Syntaxe de la ligne de commande

TDUMP [<options>] <inputfile> [<listfile>]

Où :

  • <inputfile> désigne le fichier dont vous voulez afficher (ou "vider") la structure.
  • <listfile> est un nom facultatif de fichier de sortie (vous pouvez aussi utiliser la commande standard de redirection >).
  • <options> représente des options de la ligne de commande TDUMP.


Pour afficher l'aide de la ligne de commande, entrez :

tdump

ou

tdump -?

pour afficher l'écran d'aide étendu de la ligne de commande.


Options de la ligne de commande

Vous pouvez utiliser le caractère de préfixe / ou - devant les options. Par exemple, les deux commandes suivantes sont équivalentes :

TDUMP -e1 -v demo.exe
TDUMP /el /v demo.exe

TDUMP.EXE supporte les options de ligne de commande listées dans le tableau suivant :

Options de la ligne de commande TDUMP

Option Description
-?

Affiche l'écran d'aide étendu.

-a
-a7

TDUMP ajuste automatiquement l'affichage de sortie en fonction du type de fichier. Vous pouvez forcer un affichage de fichier au format ASCII en incluant l'option --a ou -a7.

  • -a -- produit un affichage de fichier ASCII qui montre le décalage et le contenu en caractères ASCII affichables. Un caractère non affichable (comme un caractère de contrôle) apparaît sous la forme d'un point.
  • -a7 -- convertit les caractères de la partie haute du tableau ASCII en leurs équivalents de la partie basse du tableau ASCII. Cela est utile si le fichier en cours de vidage utilise des caractères ASCII hauts comme indicateurs.
-b#

Permet d'afficher les informations commençant à un offset # décimal spécifié (préfixe hexadécimal avec 0x). Par exemple, pour obtenir un vidage de MYFILE à partir de l'offset 100, vous pouvez taper :
TDUMP -b100 MYFILE

-C

TDUMP renvoie les informations contenues dans les fichiers de format COFF (.OBJ et .LIB). Cette option est utile lors de l'établissement de liaison avec des fichiers.OBJ et .LIB Microsoft. (COFF seulement.)

-d

TDUMP renvoie les éventuelles informations de débogage Modèle:CBuilder 32 bits contenues dans le fichier .OBJ. Si cette option est absente, TDUMP n'affiche que des données brutes. (OMF seulement.)

-e
-ea[:v]
-ed
-ee[=x]
-eh
-eiID
-el
-em[=x]
-em.[x]
-ep
-er
-es[=x]
-et
-ex

Toutes ces options forcent TDUMP à afficher le fichier sous la forme d'un fichier exécutable (.EXE/DLL).
L'affichage d'un fichier exécutable se compose des informations contenues dans le fichier qui sont utilisées par le système d'exploitation pour charger ce fichier. Si des informations symboliques de débogage sont présentes, TDUMP les affiche.
TDUMP affiche des informations pour les fichiers exécutables DOS, les fichiers exécutables de NOUVEAU style (.DLLs et .EXEs OS/2 et Windows 16 bits), les fichiers exécutables linéaires (Linear Executable) et les fichiers exécutables portables (Portable Executable, PE) utilisés par Windows 32 bits (Windows 95/98/Me, Windows NT/2000/XP, et ainsi de suite).

  • -e -- Affiche le fichier comme un exécutable (EXE/DLL, DOS, Win16, OS/2, PE).
  • -ea[:v] -- Définit comment afficher tous les éléments exportés. (PE seulement.)
    • -ea -- Affiche tous les éléments exportés non triés.
    • -ea:v -- Affiche tous les éléments exportés non triés par RVA.
Par défaut, effectue seulement un vidage des éléments exportés nommés, avec tri sur le nom.
  • -ed -- Désactive les informations de débogage EXE.
  • -ee[=x] -- Liste les éléments exportés seulement depuis EXE/DLL (le paramètre facultatif x permet de ne lister que les correspondances). (PE seulement.)
  • -eh -- Désactive l'affichage des en-têtes EXE. (Elf seulement.)
  • -eiID -- Inclut seulement l'ID de table .EXE (HDR, OBJ, FIX, NAM, ENT). (PE seulement.)
  • -el -- Supprime les numéros de ligne dans l'affichage.
  • -em[=x] -- Liste les éléments importés seulement depuis EXE/DLL (le paramètre facultatif x permet de ne lister que les correspondances). (PE seulement.)
  • -em.[x] -- Liste les modules importés seulement depuis EXE/DLL (le paramètre facultatif x permet la recherche dans les chaînes). (PE seulement.)
  • -ep -- Désactive l'affichage de l'en-tête EXE PE. (PE seulement.)
  • -er -- Empêche l'affichage de la table de relogement.
  • -es[=x] -- Vidage hexadécimal des sections de programme. Utilisez x pour spécifier une section particulière. (Elf seulement.)
  • -et -- Désactive les tables de symboles EXE. (Elf seulement.)
  • -ex -- Empêche l'affichage des informations d'exécutables de Nouveau style. Cela signifie que TDUMP n'affiche que des informations pour les programmes DOS "stub".
-h[O|=x]

Affiche le fichier de vidage au format hexadécimal.

  • O -- peut prendre la valeur :
    • r -- Imprime les offsets relatifs à l'offset de début.
    • a -- Imprime les offsets absolus.
  • =x -- Offset début de fichier (identique à -b#).

Le format hexadécimal comprend une colonne de numéros d'offset, 16 colonnes de nombres hexadécimaux et leurs équivalents ASCII (un point apparaît lorsque le caractère ASCII n'est pas affichable).
Si TDUMP ne reconnaît pas l'extension du fichier d'entrée, il affiche le contenu du fichier au format hexadécimal (sauf si une option est utilisée pour indiquer un autre format).

-iID

Spécifie l'ID de la table de débogage à utiliser. ID=[?/abc...rst]. (Pas Elf.)

-xID

Spécifie l'ID de la table de débogage à exclure. ID=[?/abc...rst]. (Pas Elf.)

-l
-le[=x]
-li[=x]

Affiche le fichier de sortie sous la forme d'un fichier de bibliothèque (.LIB). (OMF LIB seulement.)
Un fichier bibliothèque est un ensemble de fichiers objet (voir l'option -o pour plus d'informations sur les fichiers objet).
Le vidage d'un fichier bibliothèque affiche les informations propres à la bibliothèque, les fichiers objet et les enregistrements qu'ils contiennent.

  • -li -- Indique à TDUMP d'afficher un format court des enregistrements IMPDEF lors du vidage de bibliothèques d'importation. Vous pouvez aussi spécifier une chaîne de recherche à l'aide de la syntaxe suivante :
-li=<string>
Par exemple, la commande suivante :
tdump -li=codeptr import32.lib
produit la sortie suivante :
Impdef:(ord) KERNEL32.0336=ISBADCODEPTR
Cette sortie montre que la fonction est exportée par ordinal, dont la valeur (décimale) est 336. En outre, la sortie affiche le nom du module et celui de la fonction.
Si vous entrez la commande suivante :
tdump -li=walk import32.lib
TDUMP affiche :
Impdef:(name) KERNEL32.????=HEAPWALK
Il s'agit là de la sortie correspondant à une fonction exportée par nom.
  • -le -- Indique à TDUMP d'afficher une forme courte des enregistrements EXDEF lors du vidage des fichiers OBJ. Vous pouvez aussi spécifier une chaîne de recherche à l'aide de la syntaxe suivante :
-le=<string>
-lm[=x]

Affiche le vidage des membres (x liste seulement les correspondances). (ELF LIB seulement.)

-lh

Affiche la liste des membres de l'archive. (ELF LIB seulement.)

-lt

Affiche les symboles exportés de l'archive. (ELF LIB seulement.)

-m

Laisse les noms C++ présents dans les fichiers objet, les fichiers exécutables et les fichiers d'informations symboliques du débogueur en format "abrégé". Cette option est utile pour déterminer comment le compilateur C++ "abrège" un nom de fonction particulier et ses arguments. (Pas Elf.)

-M

Affiche le fichier MACH. (MACH seulement.)

-ns

Désactive le support de la redirection stdin.

-o
-oc
-oiID[=x]
-oxID[=x]

Cette commande affiche le fichier sous la forme d'un fichier objet (.OBJ). (OMF seulement.)

  • -o -- affiche le fichier sous la forme d'un fichier objet (.OBJ). L'affichage d'un fichier objet contient des descriptions des enregistrements de commandes qui passent des commandes et des données au lieur, pour lui indiquer comment créer un fichier .EXE. Le format d'affichage montre chaque enregistrement et ses données associées, enregistrement par enregistrement.
  • -oc -- demande à TDUMP d'effectuer un test de redondance cyclique (CRC) sur chaque enregistrement rencontré. L'affichage ne diffère de celui produit par l'option -o que si un code CRC incorrect est rencontré (la valeur CRC de TDUMP est différente de l'octet CRC de l'enregistrement).
  • -oi<ID> -- n'inclut dans le vidage du module objet que les types d'enregistrement OMF spécifiés.
-ox<ID>[=x] -- exclut du vidage du module objet les types d'enregistrement OMF spécifiés.
Remplacez <ID> par le nom de l'enregistrement à afficher. Par exemple :
TDUMP -oiPUBDEF MYMODULE.OBJ produit un affichage de module objet pour MYMODULE.OBJ qui n'affiche que les enregistrements PUBDEF.
Les options -ox et -oi sont utiles pour trouver les erreurs se produisant pendant la liaison. En examinant l'orthographe et la casse des symboles EXTDEF et PUBDEF, vous pouvez résoudre de nombreux problèmes de liaison. Par exemple, si vous recevez du lieur un message du type "symbole externe non résolu", vous pouvez utiliser
TDUMP -oiEXTDEF pour afficher les définitions externes contenues dans le module qui provoque l'erreur. Utilisez ensuite :
TDUMP -oiPUBDEF sur le module contenant le symbole public pour lequel le lieur n'a pas trouvé de correspondance.
Le commutateur -oi permet aussi de connaître les noms et tailles des segments générés dans un module particulier. Par exemple :
TDUMP -oiSEGDEF MYMODULE.OBJ affiche les noms, attributs et tailles de tous les segments de MYMODULE.
Remarque : Pour obtenir une liste des types d'enregistrement pour -oi et -ox, utilisez les options de ligne de commande -oi? et -ox?.
-q

Supprime le message de copyright.

-r

TDUMP affiche des données brutes. (OMF seulement.)

-R

TDUMP vide les tables de relogement des images au format 32 bits PE (Win32). Par défaut, ces vidages ne sont pas présentés. (PE seulement.)

-s[=x]
-su[=x]
-s[xx]

Indique à TDUMP d'afficher des chaînes.

  • -s[=x] -- Par défaut -s affiche toutes les chaînes d'un fichier donné. x = chaîne de recherche. Vous pouvez spécifier une chaîne, ou une partie de chaîne, à l'aide de la syntaxe suivante :
-s=<string>
Par exemple, la commande :
TDUMP -s=black GoGame.exe
génère toutes les chaînes suivantes contenant black :
56840  IDI_BLACK 81965: Capture Black 85038: black.bmp
L'argument string facultatif est insensible à la casse. Pour spécifier plusieurs mots d'une chaîne, utilisez des guillemets. Par exemple :
TDUMP -s="game of go" GoGame.exe
  • -su[=x] -- indique à TDUMP d'afficher les chaînes de style Unix, c'est-à-dire sans offset (ou des offsets décimaux, -h pour les valeurs hexadécimales). L'option -su[=x] est utilisée de la même façon que -s[=x]. L'argument chaîne x facultatif définit la chaîne de recherche.
Par exemple, la commande :
TDUMP -su=black GoGame.exe
produit la sortie suivante :
IDI_BLACK Capture Black black.bmp
  • -s[xx] -- Affiche les chaînes visualisables. xx peut prendre la valeur :
    • # -- Longueur de chaîne minimale à rechercher (par défaut : 4).
    • b# -- Offset début de fichier (-b# est équivalent à -sb#).
    • e# -- Offset fin de fichier.
    • f -- Formatage (enveloppement) des chaînes longues.
    • s -- Recherche des chaînes en tenant compte de la casse (par défaut : non).
-t#

Offset fin de fichier -b# pour l'affichage (préfixe hexadécimal avec 0x). (Elf seulement.)

-ua

Désassemble en source asm. (OMF seulement.)

-um

Affiche les noms substantypés comme non substantypés. Vous n'avez pas besoin de reformater le texte pour n'éditer que les noms substantypés avant d'utiliser cette option. Vous pouvez passer une sortie présentant des noms substantypés n'importe où dans le texte, et seuls les noms substantypés seront affectés. (Pas Elf.)

-v

Affichage détaillé. (OMF et COFF seulement.)
Si elle est utilisée avec un fichier .OBJ ou .LIB, TDUMP produit un vidage hexadécimal du contenu de l'enregistrement sans générer de commentaires sur les enregistrements.
Si vous utilisez TDUMP sur une table de symboles du débogueur, elle affiche les tables d'informations dans l'ordre dans lequel elle les rencontre. TDUMP ne combine pas les informations de plusieurs tables, pour fournir un affichage plus significatif par module.

-w
-wq[#]

Définit comment utiliser les caractères génériques dans les spécifications de fichier.

  • -w -- Autorise les caractères génériques dans les spécifications de fichier.
  • -wq[#] -- Commutateur caractères génériques silencieux. # est la largeur.

2. Comprendre les messages d'erreur "Symbole non défini"

L'un des messages d'erreur les plus courants vus par les développeurs utilisant un compilateur C ou C ++ est "symbole non défini". Ce document fournit une description générale de la cause des messages d'erreur de symbole non défini, ainsi que des instructions sur la résolution d'erreurs de symbole non définies spécifiques.

Les messages d'erreur suivants sont traités dans l'ordre:

 SYMBOLE NON DÉFINI À LA COMPILATION
SYMBOLE NON DÉFINI AU MOMENT DE LA LIAISON
AUTRES ERREURS DE SYMBOLE NON DÉFINIES
o SYMBOLE NON DÉFINI LORS DE LA LIAISON À UN EXEMPLE BORLAND
o SYMBOLE NON DÉFINI LORS DE LA LIAISON À PARTIR DE LA LIGNE DE COMMANDE DOS
o SYMBOLE NON DÉFINI DE LIAISON C / C ++ ET MODULES D'ASSEMBLAGE
o SYMBOLE NON DÉFINI LIANT LE C ++ AVEC LE C OU LES MODULES D'ASSEMBLAGE
o SYMBOLE NON DÉFINI: '_main' DANS LE MODULE C0.ASM
o SYMBOLE NON DÉFINI LIANT UNE DLL
o SYMBOLE NON DÉFINI: UN REGISTRE PSEUDO (ie. _AX)
o SYMBOLE NON DÉFINI: «FIWRQQ»
o SYMBOLE NON DÉFINI: UN MEMBRE DE LA CLASSE IOSTREAM
o SYMBOLE NON DÉFINI: 'abort ()'
o SYMBOLE NON DÉFINI: '_exitclean ()'
o SYMBOLE NON DÉFINI: LLSH ou SCOPY ou FMUL ou FDIV
o SYMBOLE NON DÉFINI: POINTAGE STATIQUE VERS UNE FONCTION MEMBRE DE CLASSE
o SYMBOLE NON DÉFINI: '_WSPRINTF'
o SYMBOLE NON DÉFINI: 'fidrqq'
o SYMBOLE NON DÉFINI DANS WINDOWS.H
o SYMBOLE NON DÉFINI À L'AIDE DE TCLASDLL.LIB
o SYMBOLE NON DÉFINI À L'AIDE DE SÉLECTEURS FOURNIS PAR WINDOWS
o SYMBOLE NON DÉFINI: «ChangeSelector»
o SYMBOLES NON DÉFINIS À L'AIDE DE LA BIBLIOTHÈQUE OBJECTWINDOWS (OWL)
o SYMBOLE NON DÉFINI: 'Object :: new (unsigned int)'
OBTENIR UN REGARD PLUS PROCHE
o UTILISER TDUMP POUR RÉSOUDRE DES SYMBOLES NON DÉFINIS
o UTILISATION D'IMPDEF POUR RÉSOUDRE DES SYMBOLES NON DÉFINIS DANS UNE DLL


SYMBOLE NON DÉFINI À LA COMPILATION

Un symbole non défini au moment de la compilation indique que l'identifiant nommé a été utilisé dans le fichier source nommé, mais n'avait aucune définition dans le fichier source. Cela est généralement dû à un nom d'identificateur mal orthographié ou à une déclaration manquante de l'identifiant utilisé.

EXEMPLE 1:

 int main (void)
{
test = 1;
retourner 0;
}

Le code affiché dans l'exemple 1 génère une erreur de symbole non défini si la variable "test" n'a pas été déclarée dans un fichier d'en-tête inclus ou dans le fichier source réel lui-même.

EXEMPLE 2:

 int main (void)
{
test int;
Test = 1;
retourner 0;
}

Le code affiché dans l'exemple 2 provoque l'affichage d'un message d'erreur de symbole non défini car la variable "Test" n'a pas été orthographiée comme elle a été déclarée. N'oubliez pas que C et C ++ sont des langages sensibles à la casse.


SYMBOLE NON DÉFINI AU MOMENT DE LA LIAISON

Lors de la liaison de projets multi-fichiers, l'éditeur de liens doit résoudre toutes les références aux fonctions et aux variables globales partagées entre les modules. Lorsque ces références ne peuvent pas être résolues, l'éditeur de liens génère un message d'erreur «symbole non défini». Cela signifie qu'après avoir recherché tous les fichiers objets et bibliothèques qui sont inclus dans le lien, l'éditeur de liens n'a pas pu trouver une déclaration pour un identifiant que vous avez utilisé. Cela peut être dû à:

 Oublier d'inclure un module d'objet ou une bibliothèque dans
votre lien (fichier de projet, fichier de réponses ou ligne de commande).
 o Faute d'orthographe du nom du symbole non défini là où il
a été utilisé ou où il a été déclaré.
 o Déclaration accidentelle d'une variable globale comme «extern».
 Oublier d'utiliser extern "C" pour désactiver la manipulation de nom lorsque vous êtes
mélange de C ++ avec des modules C ou Assembly.  Voir l'entrée spécifique sur
ce sujet ailleurs dans ce document ou consultez le
Fichier HELPME! .DOC inclus avec le produit.
 o Désactivation de la génération de barres latérales dans l'un des modules que vous utilisez
mise en relation.

Si tout le reste échoue, utilisez TDUMP pour vider les deux modules objet et notez toute différence entre les symboles utilisés. Cela donnera généralement suffisamment d'informations pour résoudre le problème. Pour plus d'informations sur l'utilisation de TDUMP pour résoudre les erreurs de symbole non définies, consultez la section «Obtention d'un examen plus approfondi» dans ce document.


AUTRES ERREURS DE SYMBOLE NON DÉFINIES

La liste suivante fournit des solutions à certaines des causes les plus courantes d'erreurs de symbole non définies:

 o SYMBOLE NON DÉFINI LORS DE LA LIAISON À UN EXEMPLE BORLAND
Presque tous les exemples de Borland sont livrés avec des fichiers de projet.  Vous
doit utiliser le fichier de projet lors de la création de l'exemple pour garantir
que tous les modules nécessaires sont liés et tous les éléments nécessaires
les paramètres sont définis.
 o SYMBOLE NON DÉFINI LORS DE LA LIAISON À PARTIR DE LA LIGNE DE COMMANDE DOS
La ligne de commande TLINK doit avoir les bibliothèques suivantes
order (GRAPHICS.LIB + <user libs> + EMU.LIB + MATH (S, T, C, M, L -
pour le modèle) + C (S, T, C, M, L - pour le modèle)
 o SYMBOLE NON DÉFINI DE LIAISON C / C ++ ET MODULES D'ASSEMBLAGE
Il existe plusieurs sources d'erreurs de symbole non définies lors de la tentative
pour lier l'assemblage aux modules C ou C ++:
 o Turbo Assembler génère tous les symboles en majuscules, sauf si vous
spécifiez / ml ou / mx sur la ligne de commande d'assemblage.  Depuis C
les modules sont, par défaut, sensibles à la casse, à défaut de le faire
entraînera des symboles non définis pour tous les symboles qui sont
pas complètement en majuscule dans le (s) module (s) C.
 o Les symboles du fichier d'assemblage référencés à partir d'un C
Le module doit être déclaré à l'aide d'une directive PUBLIC.  TLINK ne
ne pas considérer les symboles qui ne sont pas déclarés PUBLICS
tente de résoudre un symbole non défini.
 o Tous les symboles du module d'assemblage référencés dans
le module C doit être prototypé / déclaré comme externe dans le C
module - le compilateur génère des erreurs de symbole non définies pour
tous les symboles non déclarés de cette manière.  De plus, tous
symboles dans le module d'assemblage référencés à partir d'un C
le module doit avoir un préfixe de soulignement.  Cette dénomination
la convention doit être utilisée dans le module d'assemblage.  Vous pouvez
soit le faire explicitement (_symbol) ou vous pouvez utiliser:
 .model <modèle de mémoire utilisé>, C
 pour le spécifier implicitement pour tous les symboles.
 REMARQUE IMPORTANTE: si vous placez des traits de soulignement devant
des routines d'assemblage et utilisent également le .model (modèle de mémoire)
Directive C, le symbole public sera généré avec deux
souligne;  par conséquent, une erreur de symbole non définie est
généré.
 Si tout le reste échoue, TDUMP les deux modules objet et notez tout
différence entre les symboles.  Cela donnera généralement assez
aperçu pour résoudre le problème.  Pour plus d'informations sur
en utilisant TDUMP pour résoudre les erreurs de symbole non définies, voir le
Section "Regarder de plus près" dans ce document.
 o SYMBOLE NON DÉFINI LIANT LE C ++ AVEC LE C OU LES MODULES D'ASSEMBLAGE
C ++ est un langage fortement typé.  Afin de prendre en charge le type sûr
liaison (ainsi que la surcharge de fonctions), Borland C ++ doit
attacher des informations aux symboles générés pour les noms de fonction
et variables.  Lorsque cela est fait, le symbole ne correspondra plus
le nom de fonction de style C standard.  Afin de lier correctement
avec C ou modules d'assemblage, le compilateur doit être informé que
le symbole doit être dans le style C standard (non codé) plutôt
que d'employer la manipulation de nom C ++ (encodé).  Cela se fait par
prototypage de la fonction comme type extern "C".  Voici un rapide
exemple:
 extern "C" int normal_c_func (float, int, char);
 Pour un exemple supplémentaire, vous voudrez peut-être regarder l'en-tête
fichiers fournis avec le produit.  Un de ces fichiers d'en-tête est
stdio.h.
 o SYMBOLE NON DÉFINI: '_main' DANS LE MODULE C0.ASM
Chaque programme DOS C doit contenir une fonction appelée main ().  Cette
est la première fonction exécutée dans votre programme.  Le nom de la fonction
doit être tout en minuscules.  Si votre programme n'en a pas,
créer une.  Si vous utilisez plusieurs fichiers source, le fichier
contient la fonction main () doit être l'un des fichiers répertoriés dans
le projet.
 Notez qu'un caractère de soulignement «_» est ajouté à tous
symboles Borland C ++ externes.
 En plus d'un symbole principal absent, mal orthographié ou mal placé,
il existe deux autres causes communes:
 o L'option "générer des barres inférieures" est désactivée.
 o La convention d'appel Pascal plutôt que l'appel C
convention est sélectionnée.


 o SYMBOLE NON DÉFINI LIANT UNE DLL
Il est relativement simple de lier une DLL à votre source:
 1) Créez un .LIB à partir du .DLL à l'aide de l'utilitaire implib de Borland.
 2) Incluez le .LIB dans votre projet si vous utilisez l'IDE ou
dans votre commande TLINK si vous utilisez la ligne de commande
compilateur ou éditeur de liens.
 3) Activez le lien sensible à la casse.
 4) Activez les exportations sensibles à la casse.
 Les problèmes liés à la liaison de C ++ avec C, l'assembly ou tout autre langage
s'appliquent toujours.  Voir les sections sur la liaison C ++, C et l'assemblage dans
ce document.
 Si le lien échoue toujours, les techniques de la section "Obtention d'un
Un examen plus approfondi "devrait vous aider à résoudre le problème.
 o SYMBOLE NON DÉFINI: UN REGISTRE PSEUDO (ie _AX)
Les pseudo-registres ne sont autorisés que dans le Borland C ++ et ANSI
modes du compilateur.  Vous pouvez modifier ce paramètre dans le
Options |  Compilateur |  Menu source.
 o SYMBOLE NON DÉFINI: «FIWRQQ»
Votre programme utilise directement des routines à virgule flottante (ou
indirectement) et vous n'avez sélectionné AUCUN pour virgule flottante.  Ou,
vous utilisez TLINK et avez oublié d'inclure EMU.LIB ou
FP87.LIB sur la ligne de commande.
 o SYMBOLE NON DÉFINI: UN MEMBRE DE LA CLASSE IOSTREAM
Si vous utilisez l'environnement de développement intégré, il vous suffit de
désactiver les options |  Compilateur |  Génération de code |  Non signé
Personnages.
 Si vous utilisez le compilateur en ligne de commande, supprimez simplement le
Option '-K'.
 o SYMBOLE NON DÉFINI: 'abort ()'
Le seul but de l'abandon est d'imprimer le message d'erreur
 "Arrêt anormal du programme"
 et quittez le programme avec un code d'erreur de 3. Cette fonction est
situé dans le code de démarrage C0.ASM.  Erreurs de l'éditeur de liens indiquant que
abort () est un symbole non défini n'est possible que si la norme
le code de démarrage n'est pas lié à un projet.  Bien que ce soit
n'est pas une pratique de développement C / C ++ courante, il faut s'y attendre
lors de la liaison dans du code écrit dans d'autres langues telles que Microsoft
Fortran, Clipper ou dans les cas où des systèmes embarqués sont
développé.  Pour résoudre le symbole non défini, extrayez l'abort ()
fonctionner à partir du code de démarrage et faire un objet séparé sur
à intégrer dans le projet.
 o SYMBOLE NON DÉFINI: '_exitclean ()'
Il existe une fonction appelée _exitclean qui est nouvelle dans Turbo C ++.
Les utilisateurs passant de Turbo C 2.0 à Turbo C ++ peuvent rencontrer
_exitclean () en tant que symbole non défini au moment du lien.  _exitclean () est
défini dans le code de démarrage Turbo C ++.  Utilisateurs créant intégré
système (code ROMable), qui n'utilisent pas le standard Turbo C ++
de démarrage, sont susceptibles de rencontrer _exitclean () en tant que
symbole indéfini.  Ces utilisateurs peuvent supprimer la fonction du
C0.ASM et créez un fichier .OBJ distinct qui peut être lié.
Une autre option serait d’acheter la source Borland C ++ RTL et de faire
les ajustements nécessaires.
 o SYMBOLE NON DÉFINI: LLSH ou SCOPY ou FMUL ou FDIV
Les fonctions d'aide ont changé leur nom de Turbo C 2.0 en
Turbo C ++.  Cela peut entraîner de nombreux problèmes de symboles non définis.
 Lorsque LLSH ou SCOPY ou FMUL ou FDIV (notez aucun soulignement ici)
apparaissent comme des symboles non définis au moment de la liaison, il est probable
le module objet ou la bibliothèque a généré du code pour appeler un assistant
fonction des bibliothèques Turbo C 2.0.  La solution est de
recompilez simplement tous les objets à partir de la source.  Vous pouvez le faire en
choisir Compiler |  BuildAll à partir du menu dans l'IDE.
 o SYMBOLE NON DÉFINI: POINTAGE STATIQUE VERS UNE FONCTION MEMBRE DE CLASSE
Tout membre statique d'une classe doit être initialisé - sinon
un membre statique génère une erreur de symbole non définie.  Le suivant
est un exemple de la façon d'initialiser un pointeur statique sur une classe
la fonction membre d'une classe est initialisée:
 // Lorsque vous testez l'initialisation d'un membre statique, vous devez
// déclare une instance de la classe dans une fonction principale;
// sinon, l'éditeur de liens n'a aucune référence qu'il doit
// essaie de résoudre, et l'erreur de symbole non défini
// ne pas être vu - vous ne saurez donc pas que votre
// l'initialisation était en erreur.
 #include <iostream.h>
 // utilisé pour permettre l'initialisation globale du pointeur de membre statique
typedef void (* fptr) ();
 // déclare une classe contenant des membres statiques
classe d'abord
{
Publique:
fptr statique statptr;
};
 // initialise les membres statiques de la classe First
fptr First :: statptr = NULL;
 int main (void) {
First fVar;
 if (fVar.statptr == NULL)
cout << "fVar.statptr est NULL:" <<
fVar.statptr << endl;
 retourner 0;
} // fin de main ()
 o SYMBOLE NON DÉFINI: '_WSPRINTF'
Désactivez les «exportations sensibles à la casse» et le «lien sensible à la casse»
les options.  Si vous utilisez l'éditeur de liens de commandes, n'utilisez pas le / c
commutateur.  Si vous appelez l'éditeur de liens à partir de la commande BCC (x)
ligne, utilisez le commutateur -lc-.  Si vous utilisez l'IDE, accédez au
boîte de dialogue des options de l'éditeur de liens et désactivez la sensibilité à la casse
commutateur.
 o SYMBOLE NON DÉFINI: 'fidrqq'
Vous obtiendrez un symbole fidrqq non défini lors de l'utilisation de la
Environnement de développement si vous avez les options |  Compilateur |  Code
Génération |  Plus |  Option virgule flottante définie sur AUCUN et vous êtes
en utilisant l'arithmétique à virgule flottante dans votre programme.  Afin de mieux
résoudre ce problème, vous devez définir l'option IDE pour Floating Point
soit au choix d'émulation, soit au choix 80x87.  Notez que
si vous choisissez un paramètre 80x87, l'application générée par le
le compilateur aura besoin d'une puce 80x87 pour être présent au moment de l'exécution.
Utilisez ce paramètre uniquement lorsque cela est vraiment approprié.
 o SYMBOLE NON DÉFINI DANS WINDOWS.H
Assurez-vous que vous utilisez le fichier windows.h fourni avec Borland
C ++, PAS le windows.h fourni avec le SDK Microsoft Windows.
Si vous incluez le fichier Microsoft windows.h, vous obtiendrez de nombreux
symboles non définis, y compris WINMAIN en majuscules et traduction du message
en minuscules.  Utilisez notre fichier windows.h au lieu de Microsoft lorsque
vous utilisez notre compilateur.
 o SYMBOLE NON DÉFINI À L'AIDE DE TCLASDLL.LIB
Pour utiliser la version DLL de la bibliothèque de classes de conteneur, vous devez faire
TOUS les éléments suivants:
 o Utilisez le grand modèle de mémoire
 o Utiliser les rappels intelligents
 o Activer le lien sensible à la casse
 o Activer les exportations sensibles à la casse
 o Utilisez la version DLL du RTL
 o Définir _CLASSDLL
 o SYMBOLE NON DÉFINI À L'AIDE DE SÉLECTEURS FOURNIS PAR WINDOWS
Si vous utilisez _C000h ou d'autres sélecteurs fournis par Windows
et ils apparaissent comme des symboles indéfinis, peut-être que vous êtes
en compilant en mode C ++ et j'ai oublié de les externaliser en "C".
 Programmation en C:
MOT EXTERNE _C000h
 Programmation en C ++:
MOT "C" externe _C000h
 o SYMBOLE NON DÉFINI: «ChangeSelector»
La fonction API ChangeSelector () de Windows a le mauvais nom dans
KERNEL.EXE pour Windows 3.0, et donc dans IMPORT.LIB.  Le nom
donné à cette fonction (et ce n'est PAS une blague) est 
PrestoChangoSelector ().
 Utilisez PrestoChangoSelector () dans votre programme à la place de
ChangeSelector () et tout ira bien.
 o SYMBOLES NON DÉFINIS À L'AIDE DE LA BIBLIOTHÈQUE OBJECTWINDOWS (OWL)
Si vous obtenez l'un des symboles suivants non définis:
 TApplication (caractère non signé jusqu'à présent *, entier non signé, entier non signé,
caractère non signé far *, int)
 et
 TWindow :: TWindow (TWindowsObject près de *, caractère non signé loin *,
Module près de *)
 et utilisent les versions DLL d'OWL et de la bibliothèque de classes,
vous devez définir _CLASSDLL dans Options |  Compilateur |  Code
Génération |  définit la zone de liste déroulante.
 Cela peut être dû au fait que vous avez forcé des caractères non signés.  le
les fonctions dans le .lib prennent des caractères signés et donc si vous
compiler pour utiliser des caractères non signés, les symboles ne correspondront pas.
 En utilisant l'environnement de développement intégré, assurez-vous de
off Options |  Compilateur |  Génération de code |  Personnages non signés.
 Si vous utilisez le compilateur en ligne de commande, assurez-vous de supprimer
l'option -K pour résoudre ce problème.
 o SYMBOLE NON DÉFINI: 'Object :: new (unsigned int)'
Vous avez oublié de créer un lien avec le fichier TCLASDLL.LIB où il se trouve
défini!
 Fondamentalement, le problème est que vous mélangez à la fois STATIQUE et
Bibliothèques DYNAMIC LINK dans l'application.  Vous devez utiliser uniquement
un ou l'autre.  Si vous travaillez dans l'IDE, modifiez le
Section d'options LINKER pour les bibliothèques.
 Si vous utilisez la bibliothèque de liens dynamiques, pensez à définir
_CLASSDLL et Build All.
 Si vous utilisez le compilateur et l'éditeur de liens en ligne de commande,
assurez-vous de spécifier l'ensemble correct de fichiers de bibliothèque.  Pour spécifique
informations sur le "jeu correct de fichiers de bibliothèque", veuillez consulter le
documentation incluse avec le produit car les noms de bibliothèque ont tendance à
passer d'une version à l'autre.


OBTENIR UN REGARD PLUS PROCHE

Borland fournit des outils que vous pouvez utiliser pour déterminer exactement ce que l'éditeur de liens voit lorsqu'il essaie de faire correspondre des symboles: TDUMP et IMPDEF. Cette section fournit quelques techniques simples pour utiliser ces utilitaires pour résoudre les erreurs de symbole non définies.

 o UTILISER TDUMP POUR RÉSOUDRE DES SYMBOLES NON DÉFINIS
TDUMP peut être utilisé pour répertorier les symboles dans un .OBJ ou un .LIB statique
que l'éditeur de liens a du mal à faire correspondre.
 Tout d'abord, TDUMP le module qui essaie de référencer le symbole.
Par exemple, si main.cpp essaie d'accéder à une fonction, myfunc ()
dans myfuncs.cpp et obtient "Symbole non défini myfunc () dans
module main.cpp ",
 tdump -m -oiEXTDEF main.obj> main.ext
 Ensuite, TDUMP le module dans lequel le symbole est défini.
 tdump -m -oiPUBDEF myfuncs.obj> myfunc.pub
 À l'aide d'un éditeur de texte, recherchez le symbole associé à l'erreur dans
chaque fichier.  S'ils ne sont pas identiques, vous avez vérifié que
l'éditeur de liens a correctement généré l'erreur.  Vous devez vérifier
votre code et vérifiez que le compilateur voit la même chose
déclaration du symbole lors de la compilation de chaque module.
 Vous pouvez utiliser TDUMP pour consulter un fichier .LIB statique de la même manière que vous
regardez un .OBJ.  fichier.
 tdump -m -oiPUBDEF mystatic.lib> mystatic.pub
 Pour utiliser TDUMP avec un implib,
 tdump -m -oiTHEADR mydll.lib> mydll.pub
 Vous pouvez également utiliser IMPDEF pour afficher les symboles exportés par une DLL.


 o UTILISATION D'IMPDEF POUR RÉSOUDRE DES SYMBOLES NON DÉFINIS DANS UNE DLL
Si vous essayez de lier une DLL générée par Borland à une autre
langue ou produit et obtenez des erreurs de symbole non définies, vous
devrait vérifier que les noms ou les ordinaux qui sont
exportés par la DLL sont les mêmes que ceux attendus par votre application.
 Cela peut être fait en générant un fichier .DEF avec l'utilitaire
IMPDEF.  Par exemple, pour créer un fichier .DEF pour MY.DLL,
 impdef my.def my.dll
 Le fichier .DEF aura le nom du symbole exporté et son ordinal
nombre.  N'oubliez pas que C ++ modifie les noms.  Votre candidature doit
attendez-vous à ce que le nom du symbole mutilé appelle la fonction dans la DLL
correctement.  Cela peut être un problème si l'application est automatiquement
met en majuscule le nom du symbole avant d'essayer d'appeler la fonction.  Si
il en est ainsi, vous devez modifier la déclaration de la fonction et
recréez votre DLL.

3. Résolution des messages de l'éditeur de liens de symboles non définis

Cette section donne un aperçu du processus de liaison et aide à identifier les causes des «symboles externes non résolus».

Le code de printf () se trouve dans un module de la bibliothèque d'exécution. Lorsque vous appelez printf () dans un module C / C ++, le compilateur crée un enregistrement (appelé EXTDEF - EXTernal DEFinition) qui indique l'appel à une fonction externe. L'éditeur de liens examine ensuite cet OBJ, ainsi que tous les autres modules et bibliothèques spécifiés et tente de trouver un autre module (.OBJ ou .LIB) qui définit / fournit le symbolprintf ().

Si l'éditeur de liens ne peut pas résoudre l'appel à printf (), l'éditeur de liens génère une erreur indiquant que printf () est un symbole non défini. Le message d'erreur, cependant, n'est très souvent pas le résultat de l'omission du module contenant le symbole recherché, mais plutôt une différence entre le nom utilisé par l'appelant (le module C / C ++ appelant printf () dans le cas mentionné ci-dessus ) et le fournisseur (la BIBLIOTHEQUE contenant le code à printf ()).

Le nom * réel * de tout symbole est presque toujours différent du nom / identificateur utilisé par le programmeur. Par exemple, le * vrai * nom (par * vrai * nom nous voulons dire l'identifiant utilisé / généré par les outils) de strcpy () est: '_strcpy ()'. Le nom * réel * d'un symbole dépend des différents paramètres et options. Les paramètres pertinents sont listés ci-dessous:

 Conventions d'appel:
> cdecl
> pascal
> fastcall
 Paramètres du compilateur:
> générer des sous-barres
> caractères non signés (C ++ uniquement)
 Optimisations:
> Appel de données d'objets (C ++ uniquement)
 Table virtuelle:
> Tables virtuelles lointaines
 Langue utilisée:
> C
> C ++
> Assemblage

En outre, deux options affectent la façon dont l'éditeur de liens tente de faire correspondre les symboles:

 > Lien sensible à la casse
> Exportations sensibles à la casse (Windows uniquement)

Ce qui suit est une discussion de la façon dont les options mentionnées ci-dessus affectent le nom * réel * des symboles, d'où la résolution des symboles.


Conventions d'appel

Borland et Turbo C ++ vous permettent tous les deux de spécifier la convention d'appel par défaut. Cette valeur par défaut peut être remplacée à l'aide des mots clés «pascal», «_fastcall» ou «cdecl». Qu'elle soit définie globalement ou sur des instances de fonction individuelles, la convention d'appel affecte le nom des fonctions. Par défaut, lorsque le compilateur rencontre une fonction déclarée comme,

 int Foo (int);  // ou: int cdecl Foo (int);

le nom généré est _Foo; c'est-à-dire que le nom résultant a la même casse mais est précédé d'un trait de soulignement de tête. La génération du trait de soulignement est le comportement par défaut et est nécessaire lorsque vous vous connectez aux bibliothèques d'exécution. Il n'y a pas de symbole 'printf ()' dans le RTL (!), Mais il y a un '_printf ()'.

Alors que la convention d'appel C implique la «respect de la casse» et la «génération de barres de dessous», Borland / Turbo C ++ fournit des paramètres distincts pour la génération de barres de dessous et la convention d'appel de génération de barres de dessous peut être contrôlée à partir du menu Options | Compilateur | Boîte de dialogue de génération de code avancée ou l'option -u de la ligne de commande (-u- la désactiverait, elle est activée par défaut). La «Convention d'appel» peut être modifiée via Options | Compilateur | Boîte de dialogue Entry / ExitCode.

Si notre fonction 'Foo' est déclarée avec le modificateur pascal, par exemple:

 int pascal Foo (int);

(ou si la «Convention d'appel par défaut» est définie sur «PASCAL»), le nom résultant sera FOO - c'est-à-dire, tout en majuscules sans trait de soulignement. Le modificateur '_fastcall' est similaire à 'cdecl' en ce qui concerne la sensibilité à la casse mais le caractère de soulignement est remplacé par '@'. Par conséquent:

 int _fastcall Foo (int);

entraînera le symbole «@Foo».

Par conséquent, la non-concordance des conventions d'appel peut entraîner des «symboles non définis». Surveillez les indices dans le nom de symbole non défini fourni dans les messages d'erreur de l'éditeur de liens (regardez la sensibilité à la casse et les caractères principaux) pour repérer les cas de paramètres incorrects dans la `` Convention d'appel et / ou la `` Génération de barres de dessous .


NOM MANGLING:

Le langage C ++ utilise encore une autre convention de dénomination dans le cadre de son implémentation de «liaison sécurisée de type». Imaginez une fonction myfunc () qui prend deux longs [void myfunc (long, long);]. Que faire si quelqu'un l'a incorrectement prototypé dans un module appelant comme prenant deux flottants, par exemple void myfunc (float, float) ;. Les résultats d'un tel appel seront imprévisibles. Lors de l'utilisation du langage C, l'éditeur de liens résoudrait un tel appel car le symbole utilisé par le compilateur pour appeler la fonction prenant deux flottants sera '_myfunc ()', et le nom du compilateur utilisé dans le module qui implémente la fonction prenant deux longs est également '_myfunc ()'.

En C ++, cependant, le nom que le compilateur génère pour une fonction est un nom «déformé»: il est «chiffré» en fonction des types de paramètres attendus par la fonction. Dans le scénario décrit dans le paragraphe précédent, l'appel à myfunc () ne sera pas résolu car le compilateur génère des noms différents pour «void myfunc (float, float)» et «void myfunc (long, long)».

Étant donné que le nom réel altéré d'une fonction C ++ dépend du type de ses paramètres, si des caractères non signés sont utilisés comme option de compilation, il modifie le nom des fonctions déclarées pour prendre un caractère ou caractère *. Les caractères non signés sont désactivés par défaut, ils sont activés sous Options | Compilateur | Menu de génération de code. Ou en spécifiant l'option -K avec le compilateur de ligne de commande. Méfiez-vous des messages potentiels de «symbole non défini» causés par un décalage entre le caractère et le caractère non signé.

Le «mécanisme virtuel» de C ++ est implémenté via une table communément appelée Table virtuelle ou VMT (Virtual Method Table).Divers paramètres du compilateur déterminent si la table se retrouve dans le segment de données par défaut ou dans un segment éloigné (à savoir le modèle de mémoire, les modificateurs de classe «_export» et «énorme», Virtual Table Control Optionsetc). Pour renforcer davantage la «liaison sécurisée de type», les compilateurs Borland / Turbo C ++ incluent la «distance» de la table virtuelle dans le cadre de sa logique «Name-Mangling». Cela empêche l'éditeur de liens de résoudre les appels de fonction qui se bloqueraient au moment de l'exécution en raison de paramètres de «contrôle de table virtuelle» incompatibles. Dans le même jeton, Borland fournit la «convention d'appel de données d'objets» pour une efficacité améliorée du code C ++. Une fois de plus, l'algorithme «Name-mangling» reflète également l'activation de «Object Data Calling». Cela garantit que les appels de fonction impliquant une convention «Object Data Calling» non appariée entre l'appelant et l'appelé seront interceptés au moment de la liaison (au lieu de se traduire par un comportement erratique au moment de l'exécution).

Pour illustrer l'effet de «Virtual Table Control» et «Object DataCalling», créons une classe simple et examinons les effets des différents paramètres sur les noms résultants:

Test de classe {

 Publique:

virtual int Process (vide);

};

int main (void) {

Test t;

return t.Process ();

}

Le tableau suivant illustre les effets des paramètres du compilateur sur le nom * réel * généré pour la fonction membre 'int Test :: Process (void)'.

+ ------------------------------------------------- --------- +
| Appel d'objet.  | Far V. Tbl.  |Énorme Md. | [VRAI NOM] |

| -------------- + ------------- + -------------------- --------- +

|  Non |  Non | Non> @ Test @ Process $ qv |

| -------------- + ------------- + -------------------- --------- +

|  Non |  Oui | Non> @ Test @ 0Process $ qv |

| -------------- + ------------- + -------------------- --------- +

|  Oui |  Non | Non> @ Test @ 1Process $ qv |

| -------------- + ------------- + -------------------- --------- +

|  Oui |  Non | Oui> @ Test @ 2Process $ qv |

+ -------------- + ------------- + -------------------- --------- +

REMARQUE: Utilisation du mot clé «_export» ou «énorme» lors de la définition d'une classe

entraîne des tables virtuelles éloignées pour la classe.

Les «messages de symbole non définis» provoqués par des contrôles de table virtuelle ou des conventions d'appel de données d'objets incompatibles peuvent être difficiles à identifier; il est souvent utile d'utiliser TDUMP.EXE pour trouver les noms réels des symboles non résolus (cependant, faites attention aux «0», «1» ou «2» suivant la partie «@ ClassName @» des vrais noms).


LANGUE UTILISÉE

Par défaut, les assembleurs (y compris TASM) ne modifient pas les noms publics - ils convertissent simplement les symboles en majuscules. Avec TASM, l'option / mx force l'assembleur à traiter les symboles publics avec respect de la casse. Sans / mx, un appel à _myfunc à partir d'un module d'assemblage ressemble à _MYFUNC à l'éditeur de liens (cela provoque des erreurs de symbole non définies lors de la liaison de C et d'assemblage).

REMARQUE: TASM a une extension qui provoque la génération automatique de soulignements. Voir. .MODEL <model>, Directives linguistiques dans le Guide de l'utilisateur TASM.

Comme mentionné précédemment dans la section «Name Mangling», le langage C ++ utilise une convention de dénomination différente de celle du langage C. Cela peut entraîner des symboles non définis lors de l'appel de C à partir de C ++ (ou vice-versa). Les modules C ++ doivent utiliser la syntaxe 'extern "C"' lors de l'interfaçage avec les modules C (voir la section Gestion des noms du Guide du programmeur pour la syntaxe appropriée).


PARAMÈTRES DE LINKER

Par défaut, l'éditeur de liens traite _myfunc et _MYFUNC comme des symboles différents. Cependant, vous pouvez contrôler si l'éditeur de liens fait attention à la sensibilité à la casse via les options | Linker | Boîte de dialogue Paramètres (IDE) ou l'option / c avec TLINK (/ c: active la sensibilité à la casse [par défaut], / c désactive l'option).

Par exemple, si l'option est désactivée, un appel à _myfunc pourrait être résolu en _MYFUNC.

Lors de la création d'une application Windows, non seulement vous pouvez vous lier à des modules «statiques» (.OBJ ou .LIB qui sont une collection de .OBJ), mais vous pouvez également vous lier à des bibliothèques dynamiques où la résolution de l'appel est terminée par Windows à temps de chargement. Les fonctions résidant dans des DLL et appelées à partir d'un .EXE sont censées être importées. Les fonctions codées dans un .EXE ou .DLL et appelées par Windows, .EXE ou .DLL sont censées être exportées.

Les fonctions sont importées de deux manières: en les répertoriant dans la section IMPORTS du fichier .DEF, ou en établissant un lien vers une bibliothèque d'importation. Les fonctions peuvent être exportées par deux méthodes: en utilisant le mot-clé _export dans le code source ou en répertoriant les fonctions dans la section EXPORTS du fichier .DEF.

Supposons que votre application appelle le symbole _myfunc qui se trouve dans une DLL. L'éditeur de liens peut traiter les symboles provenant d'une bibliothèque d'importation ou de la section IMPORTS du fichier .DEF avec ou sans respect de la casse (déterminé par le réglage des exportations sensibles à la casse sous Options | Linker | Boîte de dialogue Paramètres ou l'option / C de la commande TLINK ligne). Si ce paramètre n'est PAS activé, l'éditeur de liens traite les symboles dans les bibliothèques d'importation ou les sections IMPORTS comme des majuscules. Il considère ensuite les symboles majuscules pendant la phase de liaison. À ce stade, il effectue une liaison normale en utilisant le paramètre de l'option de lien sensible à la casse. Si nous importons à la fois _myfunc et _MYFUNC sans l'option / C, l'éditeur de liens peut uniquement résoudre l'appel à _MYFUNC.

Si vous appelez _myfunc (une fonction cdecl) et effectuez un lien sensible à la casse, mais que vous n'avez pas de sensibilité à la casse sur EXPORTS, _myfunc apparaîtra comme non défini.

> Les fonctions cdecl importées et les noms C ++ seront liés lorsque / c

> et / C sont tous deux activés, ou aucun n'est activé.

Les noms C ++ sont toujours générés avec des lettres minuscules. Lors de l'importation ou de l'exportation de noms C ++, il est recommandé d'utiliser à la fois les options / c et / C.

Appliquons maintenant ce qui précède à certains scénarios courants et fournissons des diagnostics et suggestions possibles:


PROBLÈME:

Toutes les fonctions d'une bibliothèque tierce ne sont pas définies!

SOLUTION:

Les bibliothèques tierces doivent être explicitement liées. Pour

créer un lien vers une bibliothèque tierce à partir de l'IDE, ouvrir un fichier de projet et insérez le fichier .LIB dans le fichier de projet. Le dossier de projet a également doit contenir tous vos fichiers de code source. De la ligne de commande, insérez le .LIB sur votre ligne de commande à TLINK.


PROBLÈME:

Toutes les fonctions du RTL ne sont pas définies!

SOLUTION:

Vous devez créer un lien dans Cx.LIB, où x est le modèle de mémoire.  UNE

caractéristique de l'IDE dans Turbo C ++ et Borland C ++ v2.x est que si vous mettez un .LIB dans le fichier de projet qui commence comme Cx où x est un modèle de mémoire, la nouvelle bibliothèque remplace le temps d'exécution normal bibliothèque, et cette dernière ne sera pas liée (par exemple, si vous utilisez une bibliothèque nommée CSERVE.LIB). Renommer un tel bibliothèques, alors le Cx.LIB normal sera automatiquement lié (Borland C ++ 4.x a une boîte de dialogue pour spécifier quel temps d'exécution Les bibliothèques doivent être liées).


PROBLÈME:

Lors du mélange de modules C et C ++ (source .c et .cpp), les symboles sont

indéfini.

SOLUTION:

En raison du changement de nom (voir ci-dessus), le symbole que l'éditeur de liens voit

être appelé à partir d'un module C ++ ne ressemblera pas au symbole le Cmodule. Pour désactiver la modification de nom lors du prototypage

les fonctions:
// SOURCE.CPP
 extern "C" {

int Cfunc1 (vide); int Cfunc2 (int);

}

REMARQUE: vous pouvez également désactiver la manipulation de nom pour les fonctions écrites en C ++ et appelées depuis C.

Une compilation C ++ se produira si le code source a une extension .CPP ou Options | Compilateur | Les options C ++ utilisent le compilateur C ++ est toujours défini.


PROBLÈME:

randomize et d'autres macros apparaissent sous forme de symboles non définis.

SOLUTION:

Transformez les mots clés en Borland C ++. Étant donné que certaines macros ne sont pas ANSI compatibles, les fichiers d'en-tête ne les définiront pas s'ils sont compilés avec les mots clés ANSI ou UNIX sur.


PROBLÈME:

min et max ne sont pas définis.

SOLUTION:

Ces macros ne sont incluses que dans une compilation C et ne seront pas

vu par le compilateur s'il compile en C ++. En C, vous devez

  1. incluez <stdlib.h> pour les utiliser.


PROBLÈME:

Je ne parviens pas à lier mes modules d'assemblage à mon programme C / C ++.

SOLUTION:

Pour C ++, voir ci-dessus. Sinon, le .ASM doit être assemblé avec respect de la casse sur les symboles publics (/ mx pour TASM). Il faut aussi correspondre à la convention d'appellation C, qui aura un trait de soulignement dans devant le nom. Donc, étant donné le code suivant dans un module C,

int myfunc (void);

tu dois

appeler _myfunc

du module d'assemblage. (REMARQUE: TASM a des extensions qui générer automatiquement des soulignements pour vous). Assurez-vous également que .OBJ qui a le code assembleur est répertorié dans le fichier projet, ou sur la ligne tlink.


PROBLÈME:

wsprintf arrive indéfini.

SOLUTION:

Dans Borland C ++ 2.0, pour utiliser wsprintf lorsque les exportations respectent la casse

est activé, vous devez inverser une définition dans windows.h via le

Suivant:
#ifdef wsprintf
  1. undef wsprintf
#define wsprintf wsprintf

extern "C" int FAR cdecl wsprintf (LPSTR, LPSTR, ...);

#fin si
Pour appeler wsprintf (ou toute fonction importée par cdecl) avec case

exportations sensibles désactivées, vous devez faire correspondre un nom en majuscule. Donc windows.h # définit le wsprintf comme WSPRINTF. wsprintf est l'un des cdecl fonctionne à partir de Windows, donc le compilateur va générer un symbole en minuscule pour l'appel.


PROBLÈME:

FIWRQQ et FIDRQQ ne sont pas définis

SOLUTION:

Ces symboles se trouvent dans la bibliothèque EMU ou FP87. Vous devez le lier explicitement lors de l'utilisation de TLINK, ou définissez l'IDE pour le lier sous les options | Compilateur | Génération de code avancée virgule flottante

boîte.


PROBLÈME:

Tentative d'avertissement pour exporter un symbole non public ...

SOLUTION:

La section des exportations du fichier .DEF a un symbole qui ne

correspondre à un compilateur généré dans le code source. Ça arrive

si:
o La source a été compilée en C ++ (le nom du symbole est modifié).

Résolvez en exportant avec le mot clé _export, en compilant en C, ou en déclarant la fonction comme externe "C".

o Les exportations sensibles à la casse sont activées, vous exportez un PASCAL

et l'exporter comme: WndProc. Résoudre par l'exportation en tant que WNDPROC ou en désactivant les exportations sensibles à la casse.

o Vous exportez une fonction cdecl. Si déclaré comme int myfunc (void); exporter en tant que _myfunc et activer les exportations sensibles à la casse (ou utilisez simplement le mot clé _export).

REMARQUE: lorsque vous utilisez le mot clé '_export', il doit être utilisé dans

le prototype de la fonction. Par exemple: int FAR _export myfunc (int);


PROBLÈME:

Problèmes de liaison C ++ et DLL.

SOLUTION:

Les classes déclarées dans la DLL doivent être déclarées comme suit:
classe _export A
{
...
};
Lorsqu'il est défini dans l'EXE, le même doit être prototypé comme:
classe énorme A
{
...
};

// voir le guide de l'utilisateur pour plus d'informations

Puis liez avec / c et / C on (lien sensible à la casse et casse

exportations sensibles ACTIVÉES) lors de la construction des fichiers .DLL et appelant.EXE.


PROBLÈME:

OWL et symboles non définis.

SOLUTION:

Si vous créez un lien vers les bibliothèques statiques:

- avec BC 2.0, liez dans owlwx.lib, tclasswx.lib et sallocwx.lib. (Vous n'avez pas besoin de sallocwx.lib avec BC v 3.x).

- ne définissez PAS _CLASSDLL dans la génération de code

ou avant d'inclure owl.h.

- lien avec / c et / C. (de l'IDE, sous l'éditeur de liens options, lien sensible à la casse et sensible à la casse exportations).

- Ne compilez PAS avec -K ou des caractères non signés activés.  Vous

obtiendra plusieurs symboles non définis dans ce cas.

Si vous vous connectez au OWL .DLL, définissez _CLASSDLL avant

y compris OWL.H, et utiliser les options de l'éditeur de liens / c et / C (les deux cas Liens sensibles et exportations sensibles à la casse ACTIVÉES).


PROBLÈME:

Avec une application OWL, wsprintf n'est pas défini dans le module lorsque

liaison aux bibliothèques statiques.

SOLUTION:

Lien avec / C (exportations sensibles à la casse activées).


PROBLÈME:

_main est un symbole non défini.

SOLUTION:

main est le point d'entrée pour chaque programme DOS C / C ++.  Assure-toi

vous écrivez une fonction appelée main (tout en minuscules) dans votre programme. Si vous avez un fichier de projet chargé, assurez-vous que votre code source fichier (fichier .c ou .cpp) qui contient le principal est répertorié dans le fichier .prj

fichier. Assurez-vous que la génération des barres de dessous est activée.


PROBLÈME:

Les membres iostream, comme << operator ne sont pas définis

SOLUTION:

Options de virage | compilateur | génération de code | caractères non signés désactivés (n'utilisez pas -K sur la ligne de commande).


PROBLÈME:

Obtention de symboles non définis LLSH, SCOPY FMUL, FDIV, etc.

SOLUTION:

De nombreuses fonctions d'assistance ont changé de nom pour Turbo C

2.0 vers Borland C ++. Ces fonctions ont été appelées depuis Turbo C 2.0. La solution consiste à recompiler tout .OBJ ou .LIB avec Borland C ++.


SNOOPING AUX VRAIS NOMS:

Un fichier .OBJ est une collection d'enregistrements. Lorsque vous appelez une fonction ou référencez un symbole non défini dans votre module, le compilateur génère un enregistrement de définition externe dans OBJ. Cet enregistrement de définition externe a le symbole que l'éditeur de liens doit résoudre. Lorsque vous définissez une fonction ou effectuez un stockage pour certaines données, le compilateur génère un enregistrement de définition public pour ce module (à moins que vous n'ayez déclaré l'élément statique, cela le rend privé pour ce module). L'une des tâches de l'éditeur de liens consiste à faire correspondre les définitions publiques et les définitions externes (PUBDEF et EXTDEF).

Pour voir les symboles auxquels le LINKER doit faire face, utilisez TDUMP.EXE fourni avec le package Borland C ++. Par exemple:

tdump -m -oiEXTDEF some.obj

Ce qui précède montre tous les enregistrements EXTDEF (définition externe) dans un fichier .OBJ. Assurez-vous d'ajouter l'option -m lors du codage en C ++.

tdump -m -oiPUBDEF some.obj

Ce qui précède affichera tous les enregistrements PUBDEF (définition publique).

Supposons que vous ayez acheté une bibliothèque tierce et un symbole à condition que la bibliothèque ne soit pas résolue; les étapes possibles pour identifier le problème pourraient inclure:

- Créer une liste de symboles dans la bibliothèque à l'aide de TLIB.  Pour
exemple:

TLIB NEWLIB.LIB, NEWLIB.LST

- TDUMP le fichier .OBJ qui a été créé à partir du .C / .CPP

module appelant la fonction souhaitée. TDUMP -m -oiEXTDEF MYCODE.OBJ MYCODE.LST

- Tenter de trouver des divergences entre le nom dans

NEWLIB.LST et celui de MYCODE.LST et vérifiez que la bibliothèque fournit en effet la fonction souhaitée.

Les programmeurs Windows trouveront l'utilitaire IMPDEF.EXE (en plus de TDUMP et TLIB) un outil très utile pour aider à identifier les symboles non résolus lorsque des DLL et / ou des bibliothèques d'importation sont impliquées.


4. Borland Open Architecture: Nom Mangling

Il existe quatre formes de base de noms codés dans Borland C ++:

1. @ className @ functionName $ args

Ce codage dénote une fonction membre Name appartenant à la classe Name et ayant des arguments args.

Les noms de classe sont encodés directement. L'exemple suivant montre un nom de classe dans un nom codé:

@nom du cours@...

Le nom de la classe peut être suivi d'un seul chiffre; la valeur numérique contient les bits suivants (ceux-ci peuvent être combinés):

0x01: la classe utilise un loin vtable
0x02: la classe utilise la convention d'appel -po

0x04: la classe a une table virtuelle compatible RTTI; ce bit est utilisé uniquement lors du codage du nom de la table virtuelle pour la classe

Le chiffre est codé comme une représentation ASCII de la valeur du masque de bits, avec 1 soustrait (de sorte que, par exemple, le préfixe de classe pour une classe 'myfunc' qui utilise des vtables éloignées serait '@ myfunc @ 0').

Voir la section suivante sur l'encodage des noms de fonction et des types d'argument.

2. @ functionName $ args

Cette forme d'encodage dénote une fonction functionName avec des arguments args.

3. @ className @ dataMember

Cette forme d'encodage dénote un membre de données statique dataMember appartenant à la classe className. Les noms des classes et des membres de données sont encodés directement. L'exemple suivant montre un membre myMember dans la classe myClass:

@ myClass @ myMember

4. @ className @

Ce nom désigne une table virtuelle pour une classe className. Comme mentionné précédemment, les noms de classe sont encodés directement.


Encodage des classes imbriquées et modèles

Le formulaire suivant code un nom de classe imbriqué lexicalement dans une autre classe:

@ externe @ interne @ ...

Une classe d'instance de modèle code le nom de la classe de modèle, ainsi que les arguments de modèle réels, de la manière suivante:

% templateName $ arg1 $ arg2 ..... $ argn%

Chaque argument réel commence par une lettre, spécifiant le type d'argument qu'il s'agit:

argument de type ot
oi argument non typé intégral
og argument de pointeur non membre non type
argument de pointeur de membre om non typé

La première lettre est suivie du type codé de l'argument. Pour un argument de type, ce code représente également la valeur réelle de l'argument. Pour les autres types d'arguments, le code de type est suivi de $ et de la valeur d'argument, codés sous la forme d'un nombre ASCII ou d'un nom de symbole. Une instance du modèle <classe T, taille int> dont le nom est vector <long, 100> est codée comme indiqué dans l'exemple suivant:

% vecteur $ tl $ ii $ 100%


Encodage des noms de fonction

Le nom de la fonction codée peut désigner un nom de fonction, une fonction telle qu'une fonction telle qu'un constructeur ou un destructeur, un opérateur surchargé ou une conversion de type.


Fonctions ordinaires

Les noms de fonctions ordinaires sont encodés directement, comme indiqué dans les exemples suivants:

foo (int) -> @ foo $ qi sna :: foo (void) -> @ sna @ foo $ qv

La chaîne $ qi dénote l'argument entier de la fonction myfunc (); '$ qv' ne dénote aucun argument dans sna :: myfunc.


Constructeurs, destructeurs et opérateurs surchargés

Les informations suivantes couvrent le codage des arguments plus en détail. Constructeurs, destructeurs et opérateurs surchargés encodés avec une séquence $ bcharacter, suivie d'une séquence de caractères du tableau suivant:

Caractère Signification Séquence
_________________________________
constructeur ctr

destructeur dtr ajouter + adr & et & arow -> arwm -> * asg = appel () cmp ~ coma, déc -- supprimer supprimer div / eql == geq> = gtr> inc ++ ind * terre && lor || leq <= lsh << lss < mod% mul * neq! = Nouveau nouveau ne pas ! ou | rand & = rdiv / = rlsh << = rmin - = rmod% = rmul * = ror | = rplu + = rrsh >> = rsh >> rxor ^ = sous - sous-marins [] xor ^ nwa new [] dla delete []

__________________________________

Les exemples suivants montrent comment les arguments sont codés avec les séquences de caractères, add, ctr et dtr du tableau précédent:

opérateur + (int) -> @ $ badd $ qi plot :: plot () -> @ plot @ $ bctr $ qv

plot :: ~ plot () -> @ plot @ $ bdtr $ qv

La chaîne $ qv ne dénote aucun argument dans le constructeur ou le destructeur de tracé.


Conversions de type

Encodage des conversions de type réalisé avec la séquence de caractères $ o, suivi de la distinction du type de retour de la conversion dans le nom de la fonction. Le type de retour suit les règles de codage des arguments, expliquées plus loin. Le manque d'arguments dans une version est rendu explicite dans le mangling en ajoutant $ qv à la fin de la chaîne encodée.

Exemple:

myfunc :: operator int () -> @ myfunc @ $ oi $ qv myfunc :: operator char * ()

-> @ myfunc @ $ opzc $ qv

Le i suivant $ o dans le premier exemple dénote int; le pzc dans le deuxième exemple dénote un pointeur proche vers un caractère non signé.


Encodage des arguments

Le nombre et les combinaisons d'arguments de fonction font de l'argument encodant l'aspect le plus complexe de la manipulation de noms.

Les listes d'arguments pour les fonctions commencent par les caractères $ q. Les qualificatifs de type sont ensuite codés comme indiqué dans le tableau suivant:

 _____________________________
Caractère Signification Séquence
_____________________________
énorme

ur _seg u non signé z signé x const w volatile

____________________________

Le codage des types intégrés suit celui des qualificatifs de type applicables, conformément au tableau suivant:

 ______________________________
Caractère Signification Séquence
______________________________
v nul

c char s court j'int l long f flotteur d double g long double e ...

______________________________

Le codage des types non intégrés suit celui des qualificatifs de type applicables, conformément au tableau suivant:

 ______________________________
Caractère Signification Séquence
______________________________
<un chiffre> (une énumération ou un nom de classe)

p près * r près & m loin & loin * un tableau Pointeur de membre M (suivi de la classe et type de base)

______________________________

L'apparition d'un ou plusieurs chiffres indique qu'une énumération ou un nom de classe suit; la valeur du ou des chiffres indique la longueur du nom, comme illustré dans les exemples suivants:

foo :: myfunc (myClass near &) est modifié comme @ foo @ myfunc $ qr7myClass

foo :: myfunc (une autre classe près de &) est modifié comme @ foo @ myfunc $ qr12anotherClass

Un caractère x ou w peut apparaître après p, r, m ou n pour indiquer un qualificatif de type constant ou volatil, respectivement. Le caractère q apparaissant après l'un de ces caractères désigne une fonction avec des arguments à suivre dans le nom codé, jusqu'à l'apparition d'un caractère $, et enfin un type de retour est codé. L'exemple suivant montre comment ces règles de codage sont appliquées:

@ foo @ myfunc $ qpxzc est modifié comme foo :: myfunc (const char near *)

@ func1 $ qxi est modifié en tant que func1 (const int) @ foo @ myfunc $ qpqii $ i is mutilé comme foo: myfunc (int (near *) (int, int))

Les types de tableau sont codés en tant que a, suivis d'une dimension codée en tant que nombre décimal ASCII et $, et enfin du type d'élément, comme indiqué dans l'exemple suivant.

myfunc (int (* x) [20]) est modifié comme @ myfunc $ qpa20 $ i

Les arguments codés sont concaténés dans l'ordre d'apparition dans l'appel de fonction. Le caractère t suivi d'un caractère ASCII code les arguments lorsqu'un certain nombre de types non intégrés identiques sont des arguments de fonction. Le caractère ASCII, compris entre ASCII 31H - 39Hand 61H - 7FH (1 à 9 et plus), indique le type d'argument à dupliquer, comme illustré dans l'exemple suivant:

@ plot @ func1 $ qdddiiilllpzctata est démêlé à plot :: func1 (double,

double, double, int, int, int, long, long, long, char near *, char près de *, char près de *)

Les deux séquences de caractères ta en double à la fin du nom codé désignent le dixième argument, codé en pzc.

/ ************************************************* ************************ /