web-dev-qa-db-fra.com

Que signifie la "référence non définie à varName" en C?

J'ai 2 fichiers: a.c et b.c

Dans a.c J'envoie un signal à une fonction située dans b.c

signal(SIGUSR1,doSomething);

En plus du fichier a.c, j'ai:

extern void doSomething (int    sig);

Cependant, lorsque je compile, j'obtiens une erreur:

/tmp/ccCw9Yun.o: Dans la fonction main':
a.c:(.text+0xba): undefined reference to
faire quelque chose'
collect2: ld a renvoyé 1 état de sortie

Les en-têtes suivants sont inclus:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

Comment puis-je réparer ça?

15
JAM

Vous devez lier à la fois a.o Et b.o:

gcc -o program a.c b.c

Si vous avez une main() dans chaque fichier, vous ne pouvez pas les lier ensemble.

Cependant, votre fichier a.c Contient une référence à doSomething() et s'attend à être lié à un fichier source qui définit doSomething() et ne définit aucune fonction définie dans a.c (Comme main()).

Vous ne pouvez pas appeler une fonction du processus B à partir du processus A. Vous ne pouvez pas envoyer de signal à une fonction; vous envoyez des signaux aux processus à l'aide de l'appel système kill().

La fonction signal() spécifie quelle fonction de votre processus (programme) actuel va gérer le signal lorsque votre processus le recevra.

Vous avez un travail sérieux à faire pour comprendre comment cela va fonctionner - comment ProgramA va savoir à quel ID de processus envoyer le signal. Le code dans b.c Devra appeler signal() avec dosomething comme gestionnaire de signal. Le code dans a.c Va simplement envoyer le signal à l'autre processus.

17

C'est un très mauvais style de définir des interfaces externes dans des fichiers .c. .

Vous devriez faire ceci

a.h

    extern void doSomething (int    sig);

a.c

    void doSomething (int    sig)
    {
       ... do stuff 
    }

avant JC

#include "a.h"
.....
signal(SIGNAL, doSomething); 

.

10
mattnz

Une première réaction à cela serait de demander et de s'assurer que les deux fichiers objets sont liés ensemble. Cela se fait au stade de la compilation en compilant les deux fichiers en même temps:

gcc -o programName a.c b.c

Ou si vous souhaitez compiler séparément, ce serait:

gcc -c a.c
gcc -c b.c
gcc -o programName a.o b.o
4
Roadrunner-EX

Vous obtenez une erreur de l'éditeur de liens, donc votre extern fonctionne (le compilateur a compilé a.c Sans problème), mais quand il est allé lier les fichiers objets ensemble à la fin, il n'a pas pu résoudre votre extern - void doSomething(int); n'a été trouvé nulle part. Avez-vous gâché l'externe? Assurez-vous qu'il existe réellement un doSomething défini dans b.c Qui prend un int et renvoie void, et assurez-vous que vous vous êtes souvenu d'inclure b.c dans votre liste de fichiers (c'est-à-dire que vous faites quelque chose comme gcc a.c b.c, pas seulement gcc a.c)

3
Michael Mrozek

Vous devez compiler puis lier les fichiers objets comme ceci:

gcc -c a.c  
gcc -c b.c  
gcc a.o b.o -o prog  
3
perreal

assurez-vous que votre fonction doSomething n'est pas statique.

1
Ram