Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I, at the moment have a pmode bootsector that loads my C kernel to 1MB. I wrote some basic print functions and put them in seperate .h and .c files. When I go to compile the files together using DJGPP, I get these errors:
main.c: undefined reference to '_clear_screen'
main.c: undefined reference to '_printk'
main.c: undefined reference to '_printk'
main.c: undefined reference to '_printk'
On a guess, though, what is happening is that either you haven't put function prototypes for [tt]printk()[/tt] and and [tt]clear_screen()[/tt] in the matching header files, or else you aren't including the header files in your [tt]main.c[/tt] file.
Also, while you specify flat-binary object format for [tt]bootpm.asm[/tt], and a.out object format for [tt]ks.asm[/tt], you seem to be leaving the C code at the default object format, which is ELF. Aside from the problems of linking ELF to a.out, there are also differnces in how it handles extern function names; specifically, it does not automatically assume that extern functions are prefixed with an underscore. If the function manes are prefixed, but the prototypes are not (as would be the case with traditional C compilers and linkers), the link will break under ELF, IIUC.
Also, what is '[tt]kernel.bin[/tt]'? Is this supposed to be [tt]bootpm.bin[/tt] (I doubt it, but I don't know what your design plans are), or is it something else entirely?
Again, we need to see your code to understand what is happening. Otherwise it's just guesswork like the stuff above.
Perica, I agree with you on the point, that one can put functions in header files.
But I have done this when i started my coding: I have put the printf and co into a header file that i intended to include in every c-file, where it is needed: BANG!!
the compiler did ok, but the linker complained about multiple declarations of a function.
So I did the following: I have buildt one module for input/output, which is actually my console driver, and then I have buildt a stdio.h-file with "extern "-declatations for the functions needed by every other module: I just include this stdio.h.
It makes life very much easier to do it this way, believe me.
For our gosh, who has the compiler complaining alot: You can import functions from other modules, when you say p.ex. EXTERN void printk(char *fn,...); Thus you tell the linker that you want to import the function located in your console-driver-module or whereever you have put printk.
When You want the linker to link to functions or variables in a nasm module, you hav to put [GLOBAL --variablename--] straight befor the concerned variable or function. --variablename stands for the label.
Just because you can do something, doesn't mean you should! It is not good practice to put code into header files. Why do people find a problem with putting all source code .c* files, and all prototypes in .h* files? You don't even know what the preprocessor will do when inserting the code into your source, why not just do this yourself?
Although I do use Perica's method of ifndef define endif for C++ header files, as you can't have multiple declarations of Class(s).
this is one way to do it *ggg* I prefer to do it a simpler way: No code in header files, but definitions and declarations. It is really good to pack things which are needed by every module into a header file and use them. this saves typing and typos.
It is just a question of how to handle things.
One thing I do not understand as I am no c guru: If I include functions in the header more than once and they aren't included due to your code, what does the linker say? Where is the function? Is it then included more than one time? Is it then included and compiled in EVERY Module where you need f. ex. printf?
This is why I rather prefer to use the EXTERN declaration in the header file.
As your only putting prototypes (functions with no code block) into your Header files, only prototypes will be included in every file, not the functions with code block. It would be the same effect as adding a
to every file which used someFunc, but instead of having to type every prototype used by a source file you just include a header file with all the prototypes contained in it.
This will Stop the Same functions from Being included more than once
oh yeah, it will prevent you from having the same function declared several times *in the same compiled object* ... but if you have several .C that include the same .H, the compiler will compile them independently -- and you can do nothing against that.
Kernigan & Ritchie have designed .H files so that people can safely export the INTERFACE of their .C modules to other modules without any interference ... so why not simply respecting the language designer's choice ? when you buy a car, you don't change the place where steering wheel is, do you ? let's do the same with your programs ...
But what is, when I have a library module: f. ex. io.c,
which contains stuff to put characters on the screen, do formatted output .. which contains for ex. printf.
I compile this module to io.o.
What happens If i want to refer to printf in another module, say example.c. In that file I declare:
void printf( char *fn,...);
Upon linking the two together, would the linker find printf? Or would it complain about unresolved reference to printf in example.o?
it will find printf. Though having the prototype in a io.h included by both can help being sure the definition is correct and similar in both modules.
Now, watch out that under MS-DOS systems, C symbols receive a pre-pended "_" (unless you disable this behaviour with -fno-underscore or something alike)
Thus if clearscreen is in an ASM module, the linker doesn't find it cuz it looks for _clearscreen...
I gonna try this out. I don't remember clearly why I put the EXTERN before the prototypes I include in other modules. I think I have seen it somewhere in Linux source code. Maybe stdio.h.
This is Wrong, you can put Functions and any other code you like in a .h (Header) File.
No, Perica - this is true. I didn't say that it wasn't possible, but it's a bad idea...source belongs into C files, prototypes and declarations into header files...that's it...