Software Side Roads

Scenic Detours Along the Way to Release


Passing Data between Lua and C/C++

Building on the previous article describing how to embed Lua scripts in C++, this article and source code adds making global variables available in Lua scripts from the parent C++ application and calling functions in the C++ application from the Lua script using an example project in Visual Studio.

To pass data into the Lua script, one obvious way is to set global variables from the parent application. Lua generally operates in cases such as this by allowing you to push a value onto the stack and then invoking a function which operates on the stack contents. In this case, the calls for pushing a string are

  • lua_pushstring()
  • lua_setglobal()

In the other direction, the parent c++ application can register functions which are then callable from within Lua scripts.

Using the lua library as in the example, such functions must be declared as extern “C” within a C++ parent application:

extern "C" int persistlocalluastring(lua_State *L);

The sole agument is the lua state. The function extracts variables from the stack, operates on them, and returns a value. In the case of this example, it takes two strings as parameters. First, the C++ code must make sure that the correct number of values are on the stack. Then, it extracts them and uses them.

if (lua_gettop(L) != 2) { /*handle error */}

One important point not included in many examples is handling Lua nils passed as arguments to a function in the C++ application. Most ekenentary types such as numbers or strings themselves have an easy lua_tostring() representation but nil arguments are intentionally represented as NULL. For that reason, it is important to check the lua result returned for NULL values and decide whether to interpret that as the empty string or in some other way: depending on the compiler, some basic uses of NULL may seem to succeed (such as passing NULL to printf() when expecting a string or streaming to std::cout) but may fail in unpredictable ways because C++ defines the result as undefined.

In the case of C functions which must return values to Lua, two things must be done:

  • the lua_pushnumber() family of functions put values onto the Lua stack
  • The return value of the C function is the number of values that the function is returning (has pushed onto the stack)

Using these tools, we can build an applcation which:

  • Prepopulates a global variable in the Lua envrionment for the script to view.
  • Persists a value from the Lua script into the c++ application environment, either for native use or a subsequent script call
  • Provides a function in C++ which can be called from the Lua script, pass values to the C function, and return a result to the Lua script

The commented example of a c++ application embedding a Lua script and sharing data is at github.

Full source code including project files is at github repo for Lua/C++ Data Sharing.



Leave a Reply

About Me

The focus of my work is writing software tools in support of engineering and financial analysis plus taking care of the source and results data for quality and documentation purposes. Most of my professional time has been spent in the engineering, particularly naval architecture, and finance sectors. Many side tasks which aren’t strictly central to my deliverables crop up and must be dealt with. These posts are notes on the little side tours and cul-de-sacs along the way.

Newsletter

Discover more from Software Side Roads

Subscribe now to keep reading and get access to the full archive.

Continue reading