0

簡単にするために、次のような Page.h ファイルがあるとしましょう...

#ifndef PAGE_H
#define PAGE_H

typedef struct Pgmap{
    int test;
}Page;

void printPage();
#endif

Page.c が printPage() を定義し、...

#include "Page.h"

そして、上記の構造体/関数を使用する別の .c/.h ペアのファイルがあります。

Test.h で私は...

#include "Page.h"

、そして私のTest.cは持っています

#include "Test.h"

この時点で Page 構造体を使用できますが、printPage() を使用しようとすると、コンパイルしようとすると「'printPage()' への未定義の参照」エラーが発生します。

では、なぜ私のインクルードは構造体に対しては機能するのに、関数に対しては機能しないのでしょうか? 違いがある場合、私の gcc は gcc(SUSE Linux) 4.6.2 です。

4

2 に答える 2

0

ヘッダーに構造体の宣言が含まれているため機能しますが、関数のコードは C ファイルにあります。コンパイルされた C ファイル (「オブジェクト ファイル」と呼ばれる) をリンクする必要があります。

たとえば、「Page.c」を「Page.h」にコンパイルし、「Test.c」をビルドするときに、モジュールの機能が必要なため「Page.o」にもリンクします。

C では、C ファイルを使用しているという理由だけで、コンパイラは、ヘッダーで宣言されているもの (関数や外部変数など)の定義#include "something.h"を見つける方法を自動的に知りません。

#includeコンパイラは、基本的に、発生した場所に貼り付けられたヘッダーのテキストのみを認識します。コードを見つけるための魔法の方法はありません。C はバイナリ (プリコンパイル済みライブラリ) の配布をサポートしているため、対応する C ファイルがない場合もあります。

于 2014-02-11T19:27:47.277 に答える
0

私の最善の推測は、printPage() を含むモジュールにリンクしていないということです。

モジュールをコンパイルするとき、コンパイラはヘッダーに基づいて存在するものだけを認識します。構造体のレイアウトはヘッダーからわかりますが、関数の内容はわかりません。

アプリケーションがリンクされている場合は、他のモジュールを必ず含める必要があります。または、printPage() をインライン関数にします。

于 2014-02-11T19:32:52.527 に答える