[GD-General] variadic functions
Brought to you by:
vexxed72
From: Brett B. <res...@ga...> - 2003-11-27 02:21:47
|
Hiya, I'm trying to bind our scripting engine to our game engine and having trouble with variadic functions; namely I can't figure out how to call a C-implemented variadic function from our scripting engine where the parameters are not known at compile time of the engine. Of course ideally I could implement this in C itself but it seems I need to implement some assembly code to push the parameters correctly, and so maybe I shouldn't worry about the whole implementation, but I would like to understand how this works. For purposes of discussion, I'll assume the implementation is for a GCC compatible implementation. Basically, variadic functions are implemented in two steps. 1. The caller (calling the variadic function) simply pushes the parameters and calls the variadic function. 2. The callee (the variadic function) uses the following four basic functions to be able to use variable arguments (GCC compatibility style): void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src); The compiler strips the "..." off the back and makes a normal function out of the variadic one, and the preceeding four functions are then used to access these unknown parameters. The start function takes the last known parameter as a value so at first glance it seems the function knows how many paramters there are because because it can compare the last known argument with the value on the stack. The problem is that since the parameters were pushed in reverse order how would it know how many parameters there are? If it were in direct order, you could take the stack pointer minus the stack pointer at the last parameter position (which is provided) and the diffference would be the number of arguments. But since they are reversed how does the va_arg function know when to stop? I wrote a test sample for the PlayStation 2, GameCube and PC (Intel) and it seems that the caller does nothing more than push the values onto the stack as a normal function would, making sure not to use registers. Has anybody else run into this before? How did you solve it? Thanks, Brett |