10

私はいくつかの投稿を読んで、extern がコンパイラに「この関数は存在しますが、そのコードは別の場所にあります。パニックにならないでください」と伝えていると結論付けました。しかし、リンカーは関数が定義されている場所をどのように認識しますか。

私のケース:- Keil uvision 4 に取り組んでいます。ヘッダー ファイル grlib.h があり、メイン関数は grlib_demo.c (grlib.h が含まれています) にあります。現在、Circle.c で定義され、grlib_demo.c で呼び出される関数 GrCircleDraw() があり、次のステートメントもあります。

extern void GrCircleDraw(すべての引数);

grlib.h で。私の質問は、Circle.c が grlib.h と grlib_demo.c に含まれていないため、リンカが GrCircleDraw() の定義がどこにあるかを知る方法です。

注:- ファイル grlib.h と Circle.c は同じフォルダーにあります。コードは正常に実行されます。

4

4 に答える 4

9

簡単な答えは、「コンパイラーは知る必要はありませんが、リンカーはそれを見つけることができなければなりません」です。複数の.oファイルまたはライブラリを介して、リンカーは関数の単一の定義を見つけることができなければなりませんGrCircleDraw

于 2012-10-14T03:37:07.090 に答える
5

コンパイラーは、extern関数の名前だけを.objファイルに入れています。コンパイラはそれについてもっと知る必要はありません。

リンクを開始するときは、開発者として、必要なすべてのオブジェクトファイルとライブラリファイルをリンカに渡す必要があります。リンカは、これらすべての関数をバイナリに配置します。適切なライブラリまたは.objファイルを指定しないと、リンクは単に。で失敗しunresolved blah-blahます。

デフォルトのライブラリは通常、暗黙的に含まれています。これは物事を複雑にし、幻想を生み出します。暗黙的なライブラリが不要であることをいつでも指定して、すべてを明示的に含めることができます。残念ながら、すべてのシステムは独自の方法でこれを行います。

于 2012-10-14T03:49:29.827 に答える
0

通常、リンクは次のように行われます。コマンド ラインが繰り返され、指定されたすべての引数が

  1. オブジェクトファイルの場合は直接使用
  2. 必要な範囲で使用されます (= 現在まで未解決のすべての参照を満たすため)。

最後に、正常にリンクするには、すべての参照を満たす必要があります。リンカ コマンド ラインで指定される行の順序は重要です。

于 2012-10-14T04:20:16.240 に答える