Sign in to follow this  
hallgeir

Extremely weird bug in lua/luabind + template classes?

Recommended Posts

Hi. I'm trying to make a wrapper for lua and luabind - to implement some kind of scripting to my game engine. All started well, but then I suddenly got a problem (a completely illogical, weird problem). Basically what my wrapper is going to do is to register C++-classes. Here's the source code (I don't expect you to read it all, but if it can help, here it is): script_lua.h:
template<typename T>
class LuaClass
{
	//so LuaVM got directly access to lclass
	friend class LuaVM;

private:
	//the actual luabind class_
	luabind::class_<T> lclass;

public:
	//create the class object, add a constructor
	LuaClass(std::string className) : lclass(className.c_str())
	{
		lclass.def(luabind::constructor< >());
	}

	//register a new member function for the class
	void registerMember(std::string &name, void (T::*address)())
	{
		lclass.def(name.c_str(), address);
	}
};

//Main lua wrapper
class LuaVM
{
private:
	//Typedefs for storing scripts
	typedef std::vector<std::string> LuaProgram;
	typedef std::pair<std::string, LuaProgram> LuaPair;
	typedef std::map<std::string, LuaProgram> LuaScriptContainer;

	LuaScriptContainer scripts;
	lua_State *vm;

	//initialize lua
	void initialize();

public:
	LuaVM();
	LuaVM(LuaVM &obj);
	~LuaVM();

	//load a script from file, and assign a name to it
	void loadScript(std::string name, std::string path);
	
	//run the script with the specified name
	void runScript(std::string name);

	//execute a single line of code
	void executeLine(std::string line);

	//register a new class with luabind
	template<typename T> void registerClass(LuaClass<T> &luaclass)
	{
		luabind::module(vm)
		[
			luaclass.lclass
		];
	}
};

So: To register a new class with luabind (for instance the class Entity with a member function called doStuff(), and register it with the name "Entity"), I do the following (assuming I got an instance of LuaVM called vm):
LuaClass<Entity> theclass("Entity");
theclass.registerMember("dostuff", &Entity::doStuff);
vm.registerClass<Entity>(theclass);
So far so good. Except this doesn't work. For some reason, the above code doesn't register the class with luabind. I run a script, and the whole script runs, except for the part involving my class Entity. The error message I get is: [string "testentity = Entity()"]:1: attempt to call global 'Entity' (a nil value) Ok, so I decided to debug a bit. I removed the call to registerMember. Then it suddenly worked! The constructor of Entity was called, no error messages! So I supposed that my registerMember function was broken. I commented out the only line that made up the function and tried to run again. Surprise! It didn't work! I got the same error as before! So I started digging deeper. I removed all arguments for registerMember (so I basically called registerMember() without any arguments). What do you know, it worked again. I added the arguments again. Guess what - it didn't work. I then tried to pass an EMPTY std::string as the first argument. That... surprisingly worked. So it seems that ANY calls involving strings (including char arrays, I've tested) to my LuaClass-class somehow messes up the member lclass variable. I really can't understand why this should happen. Do anyone have any clue what could be going on here? Is there some limitation/little known fact about template classes (or using template classes with luabind/lua) that I don't know of? Thanks a lot for any help :) Regards, Hallgeir

Share this post


Link to post
Share on other sites
I don't know if this helps, but doesn't luabind use meta-programming in C++? Perhaps that plus templates is a no-no...

Share this post


Link to post
Share on other sites
Hmm, that might very well be. I can't find any other logical explanation at least.

Btw, a new result from my debugging:
Creating a std::string-object before registering the class = failure.

Damn, and I thought I got a good idea when I started making this class :(

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this