• ベストアンサー

分割コンパイルでのファイル利用について

分割コンパイルする際、例えばsub.cで fpi=fopen(argv[1], "rb") のようにファイルを開き、それを別のmain.cで 引き続き利用したい場合、どのようにして引き渡せば良いでしょうか? ヘッダファイルを利用してみたのですが、なぜか実行すると 「外部シンボル'_fpi'が未解決」などとエラーが出てしまいます。 ヘッダファイルについては、head.hに extern FILE *fpi,*fpo; と 入れておいて、main.cとsub.cに #include "head.h" を入力してある状態です。 使っているのは Microsoft Visual C++ Express Editionです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

設計的には、グローバル変数は避けるというのが、多くの場合有効です。 この場合、main.c で、ファイルがらみの何かの処理を sub.c に依頼して(オープンまで)、その後で、 main で使うという形でしょうから、関数の引数 or 返り値として扱う方が有効です。 【方法1】 main.c の本体で、 FILE *fpi; を定義します。 sub.c にある関数に処理を依頼するために、sub.c には、(もちろん、sub.h にも) sub(FILE *file, ... (その他の引数)) を定義して、 sub(fpi, ... (その他の引数)) で関数を呼び出す。 【方法2】 sub.c で定義する関数を FILE *sub(いろいろな引数); の形にします。 main から、 FILE *fpi; fpi = sub(必要な引数); で、fpi を使うことができます。 いずれの場合にも、ファイルのオープンに失敗したら、fpi に NULL を返すようにすればいいでしょう。 グローバル変数の危険性については、下記をご参照下さい。(「グローバル変数が多い」 や、「引数を使わずにグローバル変数を使う」)

参考URL:
http://www.cmagazine.jp/src/kinjite/c/index.html#index
mine135
質問者

お礼

方法2で出来ました。 ご丁寧にありがとうございました!

その他の回答 (3)

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.3

別の方法として head.h に #ifdef MAIN FILE *fpi, *fpo; #else extern *fpi, *fpo; #endif と定義しておき main.c では #define MAIN #include "head.h" sub.c 他では #include "head.h" とする方法もあります。

mine135
質問者

お礼

#ifdef MAINや#elseについてはまだ習っていないのですが、 参考にさせていただきます。 回答ありがとうございました!

  • peko_pee
  • ベストアンサー率53% (45/84)
回答No.2

両方のファイルで extern となっていると お互いに「どこか別のファイルでこの変数の実体が宣言されているはずだから それを使おう」と解釈して、結局どこにも変数の実体が作られないままリンク に進みます。 先の回答にもあるように、どこかのひとつのファイルで extern を付けずに 宣言しておく必要があるわけです。

mine135
質問者

お礼

>先の回答にもあるように、どこかのひとつのファイルで extern を付けずに >宣言しておく必要があるわけです。 そのようですね; 回答ありがとうございました。

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.1

sub.c には、 extern FILE *fpi, *fpo; ではなく FILE *fpi, *fpo; を入れておく必要があります。 上記を定義して、head.h を使用しないようにするか? または、上記を定義した別の global.c の様なモジュール を作成する必要があります。

mine135
質問者

お礼

externの理解が足りていませんでした; 返信ありがとうございました!

関連するQ&A