Let's see if I can shed some light on this for you. Firstly, echoing
Chris' words, I too have never written a function using var_args, but a
quick "man 3 varargs" confirmed my suspicion that var_args doesn't
actually generate a list, it merely provides a set of macros for
interpreting the arguments. The arguments themselves are passed to a
var_args function in exactly the same manner as they would be to any
other function.
>
> I'd preferably like a way to do it without having to consider each
> possible permutation of the typelist string, and I'd really like to be
> told it can be done in portable C... I could do it on a PC, with stack
> based passing using just a little hack - but thats not very portable -
> and I wouldn't have a clue how to do it so that it would work on ftoomsh
> anyway!
>
The only really portable way of generating arguments to a C function is
to let the compiler do it. Thus each instance of a function call in a C
program needs to have the number and types of its arguments determinable
at compile time. HOWEVER you can save a fair bit of work in
"considering each permutation" if you are prepared to place the
following restrictions:
a) All arguments must be POINTERS to values.
b) An upper limit on the number of arguments to be passed.
If that seems reasonable, you can take advantage of the following 2
assumptions about C compilers:
1) All pointer types occupy the same amount of memory.
2) The called function cannot tell how many arguments were
actually passed.
Oops, I just realised the first assumption isn't true on 16-bit PC
programs... in that case, the arguments must all be FAR POINTERS.
Having done that, your code will look something like this..
#define MAXIMUM_ARGS 10
void interface( char *typelist, char *instring, void *function() )
{
void * arg[MAXIMUM_ARGS];
int argc = 0;
while (...)
{
if (...)
{
char *c;
...
arg[argc++] = c;
}
else if (...)
{
int *i;
...
arg[argc++] = i;
}
else if (...)
{
float *f;
...
arg[argc++] = f;
}
}
function(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],
arg[6],arg[7],arg[8],arg[9]);
}
Note that passing more arguments than the function actually uses is OK
because of assumption 2. You may wish to type-cast the assignments to
arg[argc++] to prevent your compiler generating annoying warnings, but I
prefer to avoid casting and let the compiler (correctly) tell me I'm
doing something type-unsafe, even if it is deliberate.
> I'd appreciate any help from all you clever ppl out there.... because
> I've spent a day on it and don't have a clue!
>
> Regards,
>
> Paul
Well that's my contribution for ya. Anyone who cares to tell me I'm
wrong about anything I've said, please feel free :)
--
Cheers,
DB