tags:

views:

510

answers:

3

I have been looking for tutorials demonstrating how to share a C++ object with Lua using the API. Most tutorials just show how to export a class.

I would like to start very simple and expose a variable (say int myVar = 5) in such a way that a change in Lua will be reflected in the C++ application.

Does anyone know any good tutorials around which can show me how to do this?

+1  A: 

It sounds like you want to look at tolua++

Dirk Eddelbuettel
I was really looking to do it with Lua's API rather than using a library, but I'll give it a look.
Tom Savage
+3  A: 

Exposing your variables for direct modification using only Lua API is not all that simple. You have to create Lua table or userdata (using lua_newtable or lua_newuserdata respectively), then create a meta-table - in your case it should have the __index and __newindex events for reading and writing access and in those functions you should match your variable by name. This is no fun to write manually.

That said, it should be fairly clear that you cannot expose a variable at global Lua level - you should make it a member of a table/userdata. This will look a lot like a class/object from Lua, so just exposing a single variable is no simpler than exposing a class. What's more, exposing functions/methods is much simpler. So reading those tutorials about exposing classes will definitely help.

But using only Lua API is still no fun. Don't get me wrong, the Lua API is neat and great, but if you have a lot to expose it gets really tedious and you'll end up either writing a lot of boring repetitive code for binding you classes or writing some kind of tool to automate this task for you (using lots of macros will most probably be your first idea, been there, done that ;) ). Such tools already exist, tolua++, luabind and possibly many others.

sbk
This looks like exactly what I was looking for. Can I extend this further using a similar approach to access data like `scene.objects[5].material.diffuseColor.red`?
Tom Savage
+2  A: 

As sbk mentioned, you'd access your variable as a member of a userdata:

print(cside.myVar) -- 5

Here is some sample code to do this using the Lua API. Its straightforward, although tedious. You'll either want to make your own code generator or using something like swig or tolua++

/* gcc -o simple simple.c -llua -lm -ldl */
#include <stdio.h>

#include "lua.h"
#include "lauxlib.h"

int myVar = 5;

int l_set( lua_State *L )
{
 const char *key = luaL_checkstring(L, 2);
 int val = luaL_checkint(L, 3);

 if (strcmp(key, "myVar") == 0)
  myVar = val;
}

int l_get( lua_State *L )
{
 const char *key = luaL_checkstring(L, 2);

 if (strcmp(key, "myVar") == 0)
 {
  lua_pushinteger(L, myVar);
  return 1;
 }
}

int main(int argc, char *argv[])
{
 const struct luaL_Reg somemt[] =
 {
  { "__index", l_get   },
  { "__newindex", l_set   },
  { NULL, NULL }
 };

 lua_State *L = luaL_newstate();
 luaL_openlibs( L );

 lua_newuserdata(L, sizeof(void *));

 luaL_newmetatable(L, "somemt");
 luaL_register( L, NULL, somemt );
 lua_setmetatable(L, -2);

 lua_setglobal(L, "cside");

 luaL_dostring(L, "print('from Lua:', cside.myVar)");
 luaL_dostring(L, "cside.myVar = 200");

 printf( "from C: myVar = %d\n", myVar );
}
uroc