web-dev-qa-db-ja.com

Cの「varNameへの未定義参照」とはどういう意味ですか?

a.cb.cの2つのファイルがあります

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>

どうすれば修正できますか?

15
JAM

_a.o_と_b.o_の両方をリンクする必要があります。

_gcc -o program a.c b.c
_

各ファイルにmain()がある場合、それらをリンクすることはできません。

ただし、_a.c_ファイルにはdoSomething()への参照が含まれ、doSomething()を定義し、_a.c_(main()など)。

プロセスAからプロセスBの関数を呼び出すことはできません。関数にシグナルを送信することはできません。 kill()システムコールを使用して、プロセスにシグナルを送信します。

signal()関数は、プロセスがシグナルを受信したときに、現在のプロセス(プログラム)のどの関数がシグナルを処理するかを指定します。

これがどのように機能するか、つまりProgramAがどのプロセスIDにシグナルを送信するかをどのように知るかを理解するために、いくつかの真剣な仕事があります。 _b.c_のコードは、信号ハンドラーとしてdosomethingを指定してsignal()を呼び出す必要があります。 _a.c_のコードは、単に他のプロセスにシグナルを送信します。

17

.cファイルで外部インターフェイスを定義するのは非常に悪いスタイルです。 。

これをする必要があります

ああ

    extern void doSomething (int    sig);

交流

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

紀元前

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

10
mattnz

これに対する最初の反応は、2つのオブジェクトファイルがリンクされていることを確認することです。これは、コンパイル段階で両方のファイルを同時にコンパイルすることにより行われます。

gcc -o programName a.c b.c

または、個別にコンパイルする場合は、次のようになります。

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

リンカエラーが発生しているため、externは機能しています(コンパイラは_a.c_を問題なくコンパイルしました)が、最後にオブジェクトファイルをリンクしようとするとexternを解決できませんでした-void doSomething(int);は実際にはどこにも見つかりませんでした。外部を台無しにしましたか? doSomethingを取り、intを返す_b.c_で実際にvoidが定義されていることを確認し、_b.c_を忘れずにファイルリスト(つまり、あなたは_gcc a.c b.c_だけでなく_gcc a.c_のようなことをしています)

3
Michael Mrozek

次のようにオブジェクトファイルをコンパイルしてリンクする必要があります。

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

doSomething関数が静的でないことを確認してください。

1
Ram