Fun with SWIG

Published July 07, 2011
Advertisement
I've been exploring the use of SWIG as a Lua binding for the last day or so, and I've found I kinda like it, which surprised me. It took me a while to figure out how to use it--it appeared at first that the bindings had to be compiled into DLL modules before being used, which is cool as a feature, but absurd as a necessity. After looking around a bit, I found this GD.net forum thread, in which owl mentions the [font="Lucida Console"]luaopen_*()[/font] function that SWIG creates, allowing you to load the module from within your app. Owl gets a thanks and a +1 for that.

After that, I was toying with what I could do, and how. My initial attempt to expose objects to Lua was to use a getter function, so I could do something like [font="Lucida Console"]app = yckx.GetApp()[/font] in Lua. But it was a dirty hack and felt kludgy. I disliked writing it, much less using it. After some more Google-fu I found this mailing list thread, which solved the problem much more elegantly.

So, yay! I'm making what feels like real progress. But finding these two bits of information really tells me one thing: it's going to take a while to discover the ins-and-outs of SWIG.
0 likes 2 comments

Comments

__Homer__
I looked at SWIG among other solutions and decided that generating the bindings was just an extra step that I didn't need.

I've just implemented my own solution for lua/c++ bindings based on top of Lunar.h, which I found extremely easy to use.
In my case, I've modified the Lunar template slightly to derive from and construct for my class factory template, so all my factory-ready classes get lua bindings for free.. I can bind at runtime, too.

Here's a snippet I use to expose singleton pointers to lua, so I can then call the c++ class methods from lua eg "MyClassName:MyMethod()" (this assumes that the methods have been exposed too of course)
What I found interesting is that we can just express some new methods of such a class in lua (eg "func MyClassName:NewMethod(args)" and they are instantly callable from C++ with no extra work required :)
[code]
void Declare_Class_LuaGlobal(lua_State* L,char* name)
{
// Create a Gobal Variable "Name = this object"
lua_settop(L, 0);
int A = Lunar<T>::push(L, this);
lua_pushlstring(L,name,lstrlenA(name));
lua_pushvalue(L, A);
lua_settable(L, LUA_GLOBALSINDEX);
}
[/code]
July 09, 2011 12:07 PM
yckx
I had looked at lunar earlier, back when I was still a Lua newbie (though I'm only slightly less of one now... ) and at the time, I didn't fully grok it. Granted, a large part of that was that I was still trying to get my head around the C API; I'm still rather new to the concepts used in language bindings. Which is why I started looking at binding libraries in the first place. I think I'd make better sense of it now, but I'm making decent progress with SWIG. Managing the interface file is little more than a cut and paste from the headers, and compiling it is transparent now that I've set up a custom build rule in MSVC.

I do like the idea of defining new methods in Lua and being able to easily call them from C++, so I'll certainly look at it. Last night I implemented a callback mechanism, which took a while--first I didn't know how to write a C++ function that took a Lua function as a parameter; then I struggled with SWIG's type checking until I realized it had an implementation for Lua function pointers. The thought of being able to simply call a method in C++, despite it being written in Lua, is appealing.
July 11, 2011 10:22 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement