Что означает "undefined ссылка на varName" в C?
У меня есть 2 файла: a.c
и b.c
В a.c
Я посылаю сигнал функции, расположенной в b.c
signal(SIGUSR1,doSomething);
В верхней части файла a.c у меня есть:
extern void doSomething (int sig);
При компиляции, однако, я получаю сообщение об ошибке:
/tmp/ccCw9Yun.o: В функции main':
a.c:(.text+0xba): undefined reference to
doSomething "
collect2: ld возвращен 1 статус выхода
Включены следующие заголовки:
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
Как это исправить?
Ответы
Ответ 1
Вам нужно связать как a.o
, так и b.o
:
gcc -o program a.c b.c
Если у вас есть main()
в каждом файле, вы не можете связать их вместе.
Однако ваш файл a.c
содержит ссылку на doSomething()
и ожидает, что он будет связан с исходным файлом, который определяет doSomething()
и не определяет какую-либо функцию, определенную в a.c
(например, main()
).
Вы не можете вызывать функцию в процессе B из процесса A. Вы не можете отправить сигнал функции; вы посылаете сигналы процессам, используя системный вызов kill()
.
Функция signal()
указывает, какая функция в вашем текущем процессе (программе) будет обрабатывать сигнал, когда ваш процесс получает сигнал.
У вас есть серьезная работа, чтобы понять, как это будет работать - как ProgramA узнает, к какому идентификатору процесса нужно отправить сигнал. Код в b.c
должен будет вызвать signal()
с dosomething
в качестве обработчика сигнала. Код в a.c
просто отправит сигнал другому процессу.
Ответ 2
Очень плохой стиль для определения внешних интерфейсов в файлах .c.,
Вы должны сделать это
хиджры
extern void doSomething (int sig);
a.c
void doSomething (int sig)
{
... do stuff
}
b.c
#include "a.h"
.....
signal(SIGNAL, doSomething);
.
Ответ 3
Первоначальная реакция на это заключалась бы в том, чтобы спросить и убедиться, что два объектных файла связаны друг с другом. Это делается на этапе компиляции путем компиляции обоих файлов одновременно:
gcc -o programName a.c b.c
Или, если вы хотите скомпилировать его отдельно, это будет:
gcc -c a.c
gcc -c b.c
gcc -o programName a.o b.o
Ответ 4
Вы получаете ошибку компоновщика, поэтому ваш extern работает (компилятор скомпилирован a.c
без проблем), но когда он пошел связывать файлы объектов вместе в конце, он не смог разрешить ваш extern - void doSomething(int);
на самом деле ничего не найдено. Вы испортили экстерн? Убедитесь, что на самом деле doSomething
, определенный в b.c
, который принимает int
и возвращает void
, и убедитесь, что вы запомнили включить b.c
в список файлов (т.е. Вы делаете что-то вроде gcc a.c b.c
, а не только gcc a.c
)
Ответ 5
Вам необходимо скомпилировать, а затем связать объектные файлы следующим образом:
gcc -c a.c
gcc -c b.c
gcc a.o b.o -o prog
Ответ 6
убедитесь, что ваша функция doSomething не является статичной.