Nanashi-soft○プログラマ専用○Windows gcc SDL○
1つのソースファイルに全部書いても構わないのですが
ヒープメモリの関係上、プログラム記述しているデータなどは別ファイルにしたい事もあります
プログラムを分割する方法を説明します
例えば以下のようなソースがあるとします
・test.cの中身
#include "testsrc1.h" int main(int argc,char *argv[]){ int i; int len; len= sizeof(bmp); bmpto= (unsigned char *)malloc(len); half(bmpto, len); printf("%s\n", FILENAME); for(i=0; i < len; i++){ printf("%d\n", bmpto[i]); } free(bmpto); } void half(unsigned char *inbmp, int len){ int i; for(i=0; i < len; i++){ bmpto[i]= bmp[i] >> 1; } }
・testsrc1.hの中身
#define FILENAME "test.bmp" unsigned char *bmpto; const unsigned char bmp[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; void half(unsigned char *,int);
これを実行しようとしたらメモリ不足になったとします
そこで、bmpデータを別ソースにする事にしました
単純にbmpデータ部分のみを別ファイルにしたとします
・testsrc2.cの中身
const unsigned char bmp[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
testsrc1.hの中からbmpソースを削除します
この状態でビルドしようとすると、
$ gcc `sdl-config --cflags` -c testsrc1.c testsrc1.c: In function `SDL_main': testsrc1.c:6: error: `bmp' undeclared (first use in this function) testsrc1.c:6: error: (Each undeclared identifier is reported only once testsrc1.c:6: error: for each function it appears in.) testsrc1.c: In function `half': testsrc1.c:22: error: `bmp' undeclared (first use in this function) make: *** [testsrc1.o] Error 1
bmp変数が宣言されていないエラーが出ます
これを認識させる為には、externを宣言します
externは「中身は他で宣言済みですよ」と言う意味だと覚えておけば良いでしょう
testsrc1.hに
extern unsigned char bmp[];
を記述します
この状態でビルドしようとすると、
$ gcc `sdl-config --cflags` -c testsrc1.c testsrc1.c: In function `SDL_main': testsrc1.c:6: error: invalid application of `sizeof' to incomplete type `({anonymous})' make: *** [testsrc1.o] Error 1
sizeofが実行できないエラーがでます
externで宣言した変数にはsizeofが実行できません(そう思っておいた方がバグがでません)
ここで理解できる人だけ覚えておくと良い事を1つ
externは『宣言』ですので sizeofが使えないのは当たり前です
『宣言』は中身が無いもの、それに対して『定義』は中身が出来るものです
ですから、私は『extern宣言』と『宣言』の部分まで1くくりで覚えています
『定義』 → const unsigned char bmp[]={〜
『宣言』 → extern unsigned char bmp[];
仕方が無いので、testsrc2.cにサイズを返す関数を定義します
int bmpsize(){ return sizeof(bmp); }
それを、testsrc1.cから呼び出します
len= bmpsize(bmp);
これでビルドできるようになりました
$ gcc `sdl-config --cflags` -c testsrc1.c $ gcc `sdl-config --cflags` -c testsrc2.c $ gcc -o test testsrc1.o testsrc2.o `sdl-config --libs`
・testsrc1.c
#include "testsrc1.h" int main(int argc,char *argv[]){ int i; int len; len= bmpsize(bmp); bmpto= (unsigned char *)malloc(len); half(bmpto, len); printf("%s\n", FILENAME); for(i=0; i < len; i++){ printf("%d\n", bmpto[i]); } free(bmpto); } void half(unsigned char *inbmp, int len){ int i; for(i=0; i < len; i++){ bmpto[i]= bmp[i] >> 1; } }
・testsrc1.h
#define FILENAME "test.bmp" unsigned char *bmpto; extern const unsigned char bmp[]; void half(unsigned char *,int);
・testsrc2.c
const unsigned char bmp[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; int bmpsize(){ return sizeof(bmp); }