Skip to main content
GameDev.net gamedev.net
🔒 Locked

Error calling C++ functions from Lua with LuaBind

Started by Iced_Eagle Jul 28, 2009 at 2:42 PM 13 replies 9k views
Original Post
Iced_Eagle
Iced_Eagle
I'm tasked with implementing Lua into an existing C++ codebase. I've looked at Luna, Luabind, and tolua++ and I thought that Luabind was the most appealing choice of binding Lua and C++. After getting LuaBind all set up to compile and run, I'm having trouble getting it to work in the most basic sense. I have a ScriptingManager open up a LuaState, which is held throughout the life of the game. Later, once an object is created, I bind a very basic test function to Lua.
void testabc()
{
	return;
}

luabind::module(gScriptManager->GetState())
[
    luabind::def("testabc", &testabc)
];
Very basic, right? Well, I later have a script which merely has a function call to testabc, and is just as such: test.lua:
testabc()
This is the code that is supposed to run it, however I am getting an error code (supposedly a Yield from Lua).
void ScriptingManager::Run(const char* script)
{
	int ret = luaL_dofile(m_luaState, script);
	if(ret != 0)
	{
		if(!lua_isstring(m_luaState, lua_gettop(m_luaState)))
		{
			return;
			
		}

		std::string err = lua_tostring(m_luaState, lua_gettop(m_luaState));
		lua_pop(m_luaState, 1);
	}
	
}
The return value I am getting is 1, however the error message is the following:
Quote:
void ð­ºtestabc()
That's it. Nothing descriptive, but just the function itself it seems. Can anyone help figure out what the problem is? [Edited by - Iced_Eagle on July 28, 2009 2:58:24 PM]
AverageJoeSSU
AverageJoeSSU
Well im not sure how lua bind works ... but with Luna all of my exposed functions return ints (like int main returning 1)... dont know if that helps, im not very familiar with luabind.

i just made a blog post about how i use lua... again... not sure how luabind works... but you may find some of the information useful.

------------------------------ redwoodpixel.com
Iced_Eagle
Iced_Eagle
Well, from what I looked at with Luna, you have to have specific function signatures (returning ints and taking the lua stack IIRC?). With LuaBind, you don't have to change the signatures, but instead just have to define the functions (which makes it work better with an existing codebase IMO), which is where I might be screwing up somehow...

I ran my project in Decoda (Lua IDE/Debugger) and it throws an exception when it tries to call that function, so there is definitely something wrong in setting up that function.
AverageJoeSSU
AverageJoeSSU
Quote:
Original post by Iced_Eagle
Well, from what I looked at with Luna, you have to have specific function signatures (returning ints and taking the lua stack IIRC?). With LuaBind, you don't have to change the signatures, but instead just have to define the functions (which makes it work better with an existing codebase IMO), which is where I might be screwing up somehow...

I ran my project in Decoda (Lua IDE/Debugger) and it throws an exception when it tries to call that function, so there is definitely something wrong in setting up that function.


Afraid I cant help you then. I actually like the fact that you need specific functions to get exposed... Makes things very clear (to me and my dev buddies at least.) Of course I never really gave LuaBind a fair assessment.

After looking at a tutorial you need to do 2 open's for luabind...

// Create a new lua state
lua_State *myLuaState = lua_open();

// Connect LuaBind to this lua state
luabind::open(myLuaState);


.... etc

// Add our function to the state's global scope
luabind::module(myLuaState) [
luabind::def("print_hello", print_hello)
];

You have that stuff right?

------------------------------ redwoodpixel.com
Iced_Eagle
Iced_Eagle
I actually missed the luabind::open somehow (personally, I think LuaBind's documentation is fairly poor :\). I put that right after I init Lua and load the basic libs, but it still has no change (I did a full rebuild hoping it would work, but no dice and yes I made sure that everything is getting init'ed before I define the funcs or call the script :) ).

Error message is still the same and when I debug the script, it still throws an assert, but nothing descriptive...

*Edit* BTW, thanks for your help thus far :) I'm sure it will end up being something silly, but hopefully others in the future can read and learn from my mistakes!
AverageJoeSSU
AverageJoeSSU
No problem... as you can tell from my blog post.. im trying to learn everything i can about lua for some big implementation stuff going on in my project.

Ah... one other thing is to make sure the versions line up... I used luna for 4.x in a 5.1 lua build... and it totally sucked.
------------------------------ redwoodpixel.com
Iced_Eagle
Iced_Eagle
Hehe, I did a quick sanity check by looking online for info (LuaBind only says it's for 5.0 so I freaked for a second), but starting with their 0.8 release, it supports Lua 5.1...

I'll try emailing the LuaBind email list and see if I can get any results or else I may switch to another binding library.
AverageJoeSSU
AverageJoeSSU
http://www.gamedev.net/community/forums/topic.asp?topic_id=202942

that post is a bit old but has some sound logic in it.
------------------------------ redwoodpixel.com
Iced_Eagle
Iced_Eagle
I changed the order so it loads the script, defines the func, and then runs it to no avail. I've even tried doing a vanilla "dostring" with also no results.

I'm not sure that his final solution really works for me since I'm doing a global function and not using member functions with structs and classes (yet). :
I just emailed the luabind group, so I'm hoping within a few days someone can give me something to try or look at!

I wish I could do more debugging on my own, however since I'm not familiar with Lua, I'm not sure how the stack should look before/after it runs and such, and why the only "error" I get is the function prototype. Hell, I even thought that maybe the C++ name-mangling was an issue, but extern "C" didn't seem to help either!
Iced_Eagle
Iced_Eagle
Anyone else have any thoughts?

The LuaBind email list wasn't very helpful either, so I'm thinking of switching binding libraries...
AverageJoeSSU
AverageJoeSSU
Well... one last desperation move... you can print the contents of the Global Registry (not sure about the exact name) table. This is the part in the lua state where the globals are held. Then do a test. first do a script that prints Hello, and sets a global number.. like Test = 5... then look at the global registry table and see whats there... then do your bind and function call and check it again... although leave the number there. you should see your function .. and if you do, and it looks effed up, its definitely your version of luabind.

http://www.lua.org/pil/27.3.html

i would read through those 2 pages...

http://www.lua.org/pil/24.2.3.html

there is a function for doing a stack dump.

and...
http://lua-users.org/lists/lua-l/2004-04/msg00201.html

There is a function for printing a table... which i think you can run through the GLOBAL_REGISTRY table to print all of its data (ie your function).

Although this is a lot of work for something that might not help... i strongly suggest learning all of this stuff for the future.
------------------------------ redwoodpixel.com
SecretiveLoon
SecretiveLoon
Just a thought, but try removing the & in the code:
luabind::def("testabc", &testabc)

There are some great examples here:
http://www.nuclex.org/articles/quick-introduction-to-luabind

Let me know if you crack it. LuaBind is great, though. I thoroughly recommend you stick with it.
AverageJoeSSU
AverageJoeSSU
That would actually make sense, since you dont need to reference a global function pointer. In the example there, the reference is for the member function pointer.

That is still different then a link/example that I found earlier in this thread.. which is annoying.
------------------------------ redwoodpixel.com
bobofjoe
bobofjoe
Did you check what the error from lua is?

Try using this, and see what the string contains after the file fails to run.

std::string getDebugString()		{			lua_Debug debugInfo;			int r = lua_getstack(getCurrentState(), -1, &debugInfo);			if (r == 0)			{				return "Requested stack depth exceeded current stack depth";			}			lua_getinfo(getCurrentState(), "Slun", &debugInfo);			const char * er = lua_tostring(getCurrentState(), -1);			lua_pop(getCurrentState(), 1);						std::string error = "Failure to convert error to string";			if (er)			{				error = er;			}			std::stringstream s;			s<<				"Error "<<debugInfo.event <<" at (" << debugInfo.currentline << "): " << error << "\n" << 				"\tIn a "<< debugInfo.namewhat << " " <<debugInfo.source << " function called " << debugInfo.name <<".\n" <<				"\tIn " << debugInfo.short_src << " defined at "<< debugInfo.linedefined << ".";			return s.str();		}


Edit: Upon reviewing your problem; is it possible for you to post the entirety of your binding code, including state creation; library opening; and the impleentation of your scriptManager class?
[size=1]Visit my website, rawrrawr.com

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.