All code in Lua is executed by calling a Lua function. This function must be on the Lua stack (it is a value of type “function”), and one way to do this is to use one of the Lua load APIs such as lua_load(), which compiles a chunk and leaves it on the stack as a function value. You can then call this function using lua_call() etc, but before doing so you need to get any function arguments onto the stack. Typically, you do this using the lua_pushXXX() family of APIs, which move C values onto the stack as Lua values (for example, converting a C integer to Lua number etc). Once you have done that, you use lua_call(), and Lua starts running the function, passing it the values you pushed as arguments. When the function returns, Lua will stop executing, and return from the lua_call() API, with any return values left on the Lua stack. You can access these values in C using the lua_toXXX() family of APIs.
There are lots of variants of this sequence, but this gives you the basic idea.
While Lua is running a function via lua_call(), it might well call a C function supplied by you. In this case, Lua calls the C function (supplied by you), with arguments to the function passed on the stack, which (again) you can access using lua_toXXX(). To return values back to Lua, you push them onto the Lua stack (using lua_pushXXX() APIs).