With respect to your compiler errors:
int QGetSize(queue *);
ERROR: parse error at near '*'
This is probably because you're not including extern.h or if you are,
the typedef of 'queue' isn't being defined. C gets very confused if
it finds a word that should be a type but hasn't (yet) been defined as one.
int QGetSize(queue);
ERROR: invalid functions argument declaration
Same as above. The definition must appear before the use.
int QGetSize(struct *);
ERROR: parse error at near '*'
This is invalid. 'struct' is not a type; 'struct queue' is the type.
That is, you need to specify the type tag after 'struct' for it to
have meaning.
int QGetSize(struct);
ERROR: parse error at near ')'
Ditto. Also, the compiler is expecting another word after the
'struct' and gets very confused if there isn't one.
int QGetSize(struct queue *);
WARNING: struct declared inside parameter list
This means that type 'struct queue' has not been defined. Which it
hasn't. 'typedef struct { ... } queue' is different from
'struct queue { ... }'.
So here's some advice:
Firstly, standard practice is to wrap the body of a header file with
an '#ifndef' to ensure it only gets included once:
#ifndef __HDR_H
#define __HDR_H
... code goes here ...
#endif
(__HDR_H has to be unique and is usually a variation of the filename.)
Then, you can always #include the header that defines your types into
any file that uses them. The #ifndef (usually) lets you include with
impunity.
Secondly, you need to figure out the difference between struct tags
and typedefs.
A struct tag is the name of a particular struct definition:
struct queue { ... }; // Defines struct queue
struct queue foo; // foo is a queue structure.
A typedef is an alias to an existing type:
typedef int HANDLE; // HANDLE is just another way of saying 'int'
typedef struct queue QUEUE; // QUEUE is shorthand for 'struct queue'
The two are very different things. The first defines a specific type
of structure while the second creates a new name for an existing type.
You can, in fact, combine them:
typedef struct queue { ... } QUEUE;
and you often want to, especially if 'struct queue' contains a pointer
to another 'struct queue'.
So in this:
QUEUE foo;
struct queue bar;
'foo' and 'bar' have exactly the same type.
(Also, semi-related to this: it's common practice in C to make typedef
names all uppercase.)
Thirdly, you should use typedef sparingly. In your case, I suggest
getting rid of it entirely and just always using the 'struct'
keyword. This makes it a lot easier to know what's going on since
local struct variables have 'struct' in their declaration so the
casual reader can see that it's a struct and not, say, a renamed int.
More importantly, it lets the compiler give you more meaningful error
messages. If the struct is undefined and the compiler sees something
like this:
int foo(struct bar x);
it knows that bar is a struct and so the whole thing is a parameter
declaration and can tell you that 'struct bar' is undefined. If it
sees this, however:
int foo(BAR x);
it has no idea what BAR is supposed to be, so the error message tends
to be a big WTF?!?!?!?!? instead.
Finally, if you use the 'struct' form, you can pre-declare structs:
struct bar;
int foo (struct bar x);
struct bar { ... };
This is rarely necessary but you'll occasionally find yourself with
some really twisted circular dependencies. In that case, this can get
you out of a jam. (That's also why the last compiler warning above is
a warning and not an error; the compiler interpreted the unknown
struct argument as a forward declaration. It's legal but a bad idea.)
Anyway, I hope this helps and good luck.