Skip to main content
gamedev.net
🔒 Locked

[C++] Having problems with variable arguments function

Started by deadstar Jun 29, 2008 at 12:29 PM 3 replies 1.2k views
Original Post
deadstar
deadstar
Hi, I have a function with variable arguments that calls a Lua function. However, at the Lua end the arguments are wrong - it seems they are in the wrong order. If I do:

CallFunction("FunctionName", "ssd", "Hello", "There", 12.3);
Lua sees it as:

FunctionName("Hello", "FunctionName", Garbage float)
Here is the function:

void SYM_SCRIPT::CallFunction(string Function, const char *ArgSignature, ...)
	{
	    //Check Lua function exists
	    lua_pushstring(LuaState, Function.c_str());
        lua_rawget(LuaState, LUA_GLOBALSINDEX);
        bool Exists = lua_isfunction(LuaState, -1);
        lua_pop(LuaState, 1);

	    if(Exists)
        {
            //Number of arguments
            int NumArgs = 0;

            va_list VAList;
            va_start(VAList, ArgSignature);

            //Get function
            lua_getglobal(LuaState, Function.c_str());

            //Push arguments
            while (*ArgSignature)
            {
                switch (*ArgSignature++)
                {
                    case 'd':
                        //Double argument
                        lua_pushnumber(LuaState, va_arg(VAList, double));
                        break;

                    case 'i':
                        //Int argument
                        lua_pushnumber(LuaState, va_arg(VAList, int));
                        break;

                    case 's':
                        //String argument
                        lua_pushstring(LuaState, va_arg(VAList, char *));
                        break;

                    default: break;
                }

                NumArgs++;
            }

            //Do the call
            int Error = lua_pcall(LuaState, NumArgs, LUA_MULTRET, 0);

            //Check for errors
            LuaError(LuaState, Error);

            va_end(VAList);
        }
	}

I'm afraid I don't have the original article that showed how to write the function, but it should be pretty self explanatory. At this stage I'm trying to narrow it down to whether it's a C++ va_arg problem or a Lua problem.
"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2   A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk
RDragon1
RDragon1
luabind.
deadstar
deadstar
Quote:
Original post by RDragon1
luabind.


luabind is my next adventure, but the above is educational and I'd love to get it working.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2   A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk
Sneftel
Sneftel
Step through the function with the debugger to determine whether the arguments are being processed in the correct order.
deadstar
deadstar
I've stepped through, and the order in which arguments are retrieved doesn't make sense.

- The first returned argument is, as it should be, the first variable arg.
- The second returned argument is the FIRST argument of the function (string Function).
- Everything after seems to be garbage.

After a lot of Googling, I've found a few gotchas with the va_ functions.

MSDN confuses me, by mentioning a UNIX alternative method:
http://msdn.microsoft.com/en-us/library/kb57fad8(VS.71).aspx/* Returns the average of a variable list of integers. */#ifdef ANSI             /* ANSI compatible version    */int average( int first, ... )...#else       /* UNIX compatible version must use old-style definition.  */int average( va_alist )...


linux.about.com contradicts this, and talks about the usual va_ functions, not noting any differences between a UNIX implementation and any other platform:
http://linux.about.com/library/cmd/blcmdl3_va_arg.htmvoid 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);


cppreference.com describes the second parameter of va_start as the "mandatory first argument of the function":
First, you must have a call to va_start() passing a valid va_list and the mandatory first argument of the function.This first argument can be anything; one way to use it is to have it be an integer describing the number of parameters being passed.


whereas other references say it should be the "name of the last parameter before the variable argument list".

What is the correct way to use this set of functions? Portability is priority, I'd rather not have #ifdef's all over the place.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2   A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.