variable args

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

variable args

Brett Bibby
It's easy to create a C function interfaced to lua that can take
variable arguments, as the C function just loops through the stack.
What I need to do is to be able to pass these popped lua values to a
variadic C function.  Does anybody know how to do this?  E.g. use lua to
call a variadic function via a binding function.  Note that I can't put
the lua interface inside the variadic function directly as I'm using an
API for which I only have the library, instead I have to create a C
binding that turns around and calls the variadic function.
Thanks,
Brett


Reply | Threaded
Open this post in threaded view
|

Re: variable args

Kurt Jung-3
>What I need to do is to be able to pass these popped lua values to a
>variadic C function.

>Note that I can't put the lua interface inside the variadic function
>directly as I'm using an API for which I only have the library,
>instead I have to create a C binding that turns around and calls the
>variadic function.

Most APIs in C have an alternate entry point for each variadic function
which accepts a pointer to a list of arguments instead of an argument
list. In fact, most variadic functions are just wrappers which call
these "worker" functions. For examples in the C standard library, see
the documentation for vsprintf and vscanf.

If the API with which you are working provides this option, it would be
a relatively simple task to bundle your Lua arguments into an array and
call the "v" flavor function.

Kurt Jung



Reply | Threaded
Open this post in threaded view
|

Re: variable args

Philipp Janda
Kurt Jung schrieb:

 >What I need to do is to be able to pass these popped lua values to a
 >variadic C function.

 >Note that I can't put the lua interface inside the variadic function
 >directly as I'm using an API for which I only have the library,
 >instead I have to create a C binding that turns around and calls the
 >variadic function.

Most APIs in C have an alternate entry point for each variadic function
which accepts a pointer to a list of arguments instead of an argument
list. In fact, most variadic functions are just wrappers which call
these "worker" functions. For examples in the C standard library, see
the documentation for vsprintf and vscanf.

If the API with which you are working provides this option, it would be
a relatively simple task to bundle your Lua arguments into an array and
call the "v" flavor function.

I'm not sure whether the va_list type and an array type are compatible (a va_list can contain mixed types as members), and there are no va_list constructor functions in ISO C.

AFAIK there is no portable way to do this in general, but you could provide a binding function for the most common cases (say from one argument to 9 arguments).


Kurt Jung


Philipp



Reply | Threaded
Open this post in threaded view
|

RE: variable args

Virgil Smith
In reply to this post by Kurt Jung-3
>If the API with which you are working provides this option, it would be
>a relatively simple task to bundle your Lua arguments into an array and
>call the "v" flavor function.
>
>Kurt Jung

Great advice, but minor editing comment, "array" should be "buffer" and as
someone else pointed out this won't be portable (or at least it will have
"issues").

By "buffer" I mean you'll have to do some "nasty" C-style type mangling
using a char* into a buffer, casting it to the appropriate pointer type for
the type of argument you are currently handling, incrementing the pointer
value by an appropriate amount for that argument, and then repeating the
process.  The "issues" with this are issues such as memory access alignment
concerns and how the compiler vendor chose to implement vararg functions
(again their choices are likely to be driven by memory alignment issues and
the fact that so long as they provide suitable access macros they can shove
parameters on the stack in any manner they choose).  Also, if your platform
does not use a consistent size of pointer then you've really got "issues".

However, IIRC vararg function arguments disallow "smaller" types.  For
instance, a char, short, or int will be converted "up" to a long.  A float
will be converted "up" to a double.  With just a little luck your platform
uses a consistent pointer size, and even if it does not then varargs
functions probably "cast" all pointers to some "full" size (i.e. a "far"
pointer or similar).  Thus you may be able to reduce the number of parameter
options down to 3 (long, double, and X*), so if you have to write C helper
functions to arrange the parameters the number of helpers you need to write
is "merely" the sequence sum(i=0..N, 3^i) where N is the maximum number of
parameters.

Good Luck, and let us know how it turns out.