简体   繁体   中英

calling a c++ function from lua passes less arguments

So the function is like :

send_success(lua_State *L){

    MailService *mls = static_cast<MailService *>(lua_touserdata(L, lua_upvalueindex(1)));
    Device *dev = static_cast<Device *>(lua_touserdata(L, lua_upvalueindex(2)));
    int numArgs = lua_gettop(L);
    TRACE << "Number of arguments passed is = " << numArgs;

   /* here I do some operation to get the arguments.
    I am expecting total of 5 arguments on the stack. 
    3 arguments are passed from function call in lua 
    and 2 arguments are pushed as closure 

   */
    string one_param = lua_tostring(L, 3, NULL)
    string two_param = lua_tostring(L, 4, NULL)
    string other_param = lua_tostring(L, 5, NULL)



}

Now pushing this function on lua stack, I have done following

lua_pushstring(theLua, "sendSuccess");
lua_pushlightuserdata(theLua, (void*) mls);
lua_pushlightuserdata(theLua, (void*) this);
lua_pushcclosure(theLua, lua_send_success,2);
lua_rawset(theLua, lua_device); // this gets  me device obj in lua

calling it from lua , i would do

obj:sendSuccess("one param","second param","third param")

But when i check for the number of arguments. It should give 5 arguments. Instead only 4 arguments are passed. I did some testing whether the two objects i pass a light used data are passed correctly. They are passed correctly.

Only thing missing here is, that one parameter is missing which is passed from lua side.

Also i tried pushing only one object and it worked correctly. so I am not sure if I am messing up with argument numbering somewhere

Please tell your opinions

The user-data objects you create as part of the closure are not passed as arguments to the function, they placed in another location in the state.

That means the offsets you use to get the arguments with lua_tostring are wrong.

OK. SO the thing is

lua_pushclosure keeps the userdata in a separate space on lua_stack . Inside that stack, the offset 1 and 2 represent first and 2nd object

lua_pushlightuserdata(theLua, (void*) mls);
lua_pushlightuserdata(theLua, (void*) this);
lua_pushcclosure(theLua, lua_send_success,2);

But after that i was going to the third 3rd, assuming I had already accessed 2nd location. But that is wrong. The right thing to do is to consider that pushclousure takes only one space on stack irrespective of how many times the lightuserdata is pushed and remaining params can be accessed by starting from the 2nd offset.. so the below code works for me:

  string one_param = lua_tostring(L, 2, NULL)
  string two_param = lua_tostring(L, 3, NULL)
  string other_param = lua_tostring(L, 4, NULL)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM