Path: chuka.playstation.co.uk!news From: Nick Slaven Newsgroups: scee.yaroze.beginners Subject: Re: Object files and linking Date: Fri, 17 Jul 1998 19:02:57 +0100 Organization: PlayStation Net Yaroze (SCEE) Lines: 115 Message-ID: <35AF91D1.CCE4F782@compuserve.com> References: <35AE6952.2D94C5E9@scee.sony.co.uk> NNTP-Posting-Host: ld43-099.lon.compuserve.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 4.04 [en] (Win95; I) James Russell wrote: > This is to let the compiler know how many parameters the external function will expect, what types > those parameters will be, and what sort of variable it is going to return. If it didn't know these > things, it couldn't create the appropriate machine code. This is why you #include , so > that > the compiler knows how many/what type the variables passed to/from library functions are. > > ".h" files. > > People tend to get a bit sick of writing 'extern' this and 'void myFunction(...);' prototypes in > EVERY C file that references another object file. So they tend to create HEADER files, which > contain > all that guff, and then just #include it. So say you had a C file called "graphics.c" which > contained all your useful graphics functions, you might create "graphics.h" which contained all of > graphics.c's function prototypes, and usually any structure definitions used by graphics.c too. > This > graphics.h file can then be #include'd into your _other_ C files so that you don't have to define > the function prototypes. > > ".h" files are used in many wonderful and wierd ways, so you may see variations on this. But their > main purpose is to be included with C files so that the compiler will know the types, functions > and > variables involved. It might be worth mentioning pre processor directives (I think thats the name). For instance; say you stick all your graphics in one module, and all your game engine in another. For arguments sake lets say our files are graphics.c,graphics.h,game.c and game.h. Now lets say we have a variable in Graphics called Screen and one in Game called PadStatus. The files might look something like this. Graphics.h extern int Screen; Graphics.c int Screen; Game.h extern int PadStatus; Game.c int PadStatus; Now lets say that we have all our function prototypes in our headers as well (to save on typing). Our headers might look something like this now Graphics.h void Draw(void); extern int Screen; Game.h int GetPadStatus(void); extern int PadStatus; Now when we include Graphics.h in game.c we can see GetPadStatus and PadStatus, however when we include Graphics.h in graphics.c we will get an error generated as Screen will be declared twice, once as an extern in Graphics.h and once in Graphics.c. To get around this we use the pre processor directives #define and #ifndef #define as you know is used for macro definitions, but it can also be used to define "flags" at compile time. These "flags" can be tested for existence with #ifndef (which stands for "if not defined"). So, our header file now looks like this- Graphics.h void Draw(void); #ifndef GRAPHICS_C extern int Screen; #endif and our source file looks like this Graphics.c #define GRAPHICS_C #include "Graphics.h" #include "Game.h" so the line "extern int Screen" is only ever included in files that don't have GRAPHICS_C defined at the top. One step on - it is possible to create multiple includes of the same header in one c file this can happen when your headers include headers themselves. This can lead to all sorts of sticky problems (for instance you may get multiple references for structure definitions) causing the compiler to generate a bucket load of errors. This can be avoided by wrapping your entire header in one #ifndef statement. Our header file now looks like this. Graphics.h #ifndef GRAPHICS_H #define GRAPHICS_H void Draw(void); #ifndef GRAPHICS_C extern int Screen; #endif #endif Hmmm, this is a bit of a naff example but I hope you can see what I'm getting at, and I hope I haven't confused anybody. Cheers Nick (S)