Jump to content
  • Advertisement
Sign in to follow this  
Escarab

Luabind: Passing C++ objects

This topic is 3406 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I do remember, when I was playing with luabind 0.7, that in order to pass a C++ object(or pointer to object) to a lua function, one just needed to expose the class to luabind and pass a object as an argument to call_function. Now I'm using luabind 0.8 with lua 5.1, and... ... what I'm doing wrong?
#include <iostream>
#include<luabind/luabind.hpp>
extern "C"
  {
#include <lualib.h>
#include <lua.h>
#include <lauxlib.h>
  }

using namespace std;
using namespace luabind;
int DebuggerFunc(lua_State* L)
{

object error_msg(luabind::from_stack(L, -1));
cerr << error_msg << endl;
  return 0;
}

class teste
{
public:
 void Print(){cout<<"aaaa"<<endl;}

};


int main()
{

    try
    {
        teste *obj=new teste;

		lua_State *myLuaState = lua_open();
		luaL_openlibs(myLuaState);
        luabind::open(myLuaState);

         module(myLuaState)
            [
            class_<teste >("teste")
        .def(constructor<>())
        .def("Print", &teste::Print)
            ];

        luaL_dofile(myLuaState,"script.lua");
        luabind::call_function<void>(myLuaState,"DoStuff", obj);

        lua_close(myLuaState);

    }
    catch (const luabind::error &er)
	{
		cerr << er.what() << endl;
		lua_State* Ler=er.state();
		DebuggerFunc(Ler);
	}
	catch (...)
	{
	    cerr<<"Uknow error!"<<endl;
	}

	return 0;
}


the script is as follows: function DoStuff(obj) obj:Print() end The Error message: "lua runtime error script.lua:4: attempt to index local 'obj' (a userdata value)" If it is not the way to do it, what is then? And I've also tried with a non pointer object, same stuff. thank's

Share this post


Link to post
Share on other sites
Advertisement
Your code works fine for me. Are you sure this is the exact test case that's failing for you? Which compiler are you using, and how do you build and link to luabind?

Share this post


Link to post
Share on other sites
Yes, I'm sure, I've just copy/pasted it.

I'm Using luabind 0.8 and lua 5.1.4, my compiler is the one that comes with visual c++ 2008 express edition(using it with code::blocks).

I've download and compiled boost 1.37 with bjam, and download lua from the original website(precompiled bins for windows). Put boost in BOOST_ROOT (and BOOST_BUILD_PATH as well), and lua in LUA_PATH system variables. then, I've run bjam in luabind directory and it compiled. Everything else works but this.

There is a 8.1 version of luabind, I shall try this and see what happens.

EDIT: Luabind 0.81 = Same thing

Share this post


Link to post
Share on other sites
I verified that it works correctly for me with VC9.0Express. Can you run the test suite? "bjam toolset=msvc-9.0express test" in the luabind directory.

Share this post


Link to post
Share on other sites
Yes, I was able to do it, an it took considerably longer to finish. It has compiled a static version and a Dynamic version, debug and release.

Can you tell me what I have done? And what should I do now?

Share this post


Link to post
Share on other sites
Ok, now it works, I think code::blocks got confused, I used the same librarys I did before, but know in a new project, and it worked.

But, this test is just a simplification of a larger project I'm on, and I Get a very similar situation.


//binding, s is my lua_State variable

module(s)
[
class_<CClientBase>("CClientBase")
.def(constructor<>())

];
module(s)
[
class_<CMessengerClient,CClientBase>("CMessengerClient")
.def(constructor<>())
.def("GetId", &CMessengerClient::GetId)
];

...

//function on accept CPP


template <class CClient,class CBuffer> void CMessengerServer<CClient,CBuffer>::OnAccept(CClient* client, CBuffer* buffer,int bytes,int tn)
{
//call a lua function to deal with it
try
{
cout<<client->GetId()<<endl;
luabind::call_function<void>(lua_states[tn-1],"OnAccept",client,buffer,bytes,tn);
}
catch (const luabind::error &er)
{
cerr << er.what() << endl;
lua_State* Ler=er.state();
DebuggerFunc(Ler);
}
catch (...)
{
cerr<<"Uknow error!"<<endl;
}
}




The OnAccept C++ function just Pass on to a OnAccept lua Function

script:

function OnAccept(client,buffer,bytes,tn)
print "stuff"
print(client:GetId())

end

I know my bindings for the rest(cause there is a lot more) of my code is working, because it works till it is time to accept a connection.

For my surprise, the cout<<client->GetId()<<endl; works and print the right thing on the screen, proving it is a valid pointer, but, when its time to lua to call GetId, the program just Crashes, yeah, Crashes, no Exception catch.

the output is something like
1
stuff
CRASH!!!

Share this post


Link to post
Share on other sites
OK, now I've change to GCC (Mingw), and I'm able to Grab a Assert saying I'm trying to use an unregistered type.

My binder function (Complete):



lua_State* LuabindOpen ()
{
lua_State* s=lua_open();;
luaL_openlibs(s);
luabind::open(s);

module(s)
[
class_<CBufferBase>("CBufferBase")
.def(constructor<int>())


];

module(s)
[
class_<CMessengerBuffer,CBufferBase>("CMessengerBuffer")
.def(constructor<int>())
.def("GetBytesToSend", &CMessengerBuffer::GetBytesToSend)
];

module(s)
[
class_<CClientBase>("CClientBase")
.def(constructor<>())
];

module(s)
[
class_<CMessengerClient,CClientBase>("CMessengerClient")
.def(constructor<>())
.def("GetId", &CMessengerClient::GetId)
];

module(s)
[
class_<CServer<CMessengerClient,CMessengerBuffer> >("CServer")
.def(constructor<>())
];

module(s)
[
class_<CMessengerServer<CMessengerClient,CMessengerBuffer>, CServer<CMessengerClient,CMessengerBuffer> >("CMessengerServer")
.def(constructor<>())
.def("Start",(bool(CMessengerServer<CMessengerClient,CMessengerBuffer>::*)(int))&CMessengerServer<CMessengerClient,CMessengerBuffer>::Start)
.def("Finish", &CMessengerServer<CMessengerClient,CMessengerBuffer>::Finish)
.def("SetName", &CMessengerServer<CMessengerClient,CMessengerBuffer>::SetName)
.def("GetName", &CMessengerServer<CMessengerClient,CMessengerBuffer>::GetName)
.def("GetNumberOfProcessors", &CMessengerServer<CMessengerClient,CMessengerBuffer>::GetNumberOfProcessors)
.def("GetIp", &CMessengerServer<CMessengerClient,CMessengerBuffer>::GetIp)
.def("PostSend", &CMessengerServer<CMessengerClient,CMessengerBuffer>::PostSend)
.def("OpenLuaStates", &CMessengerServer<CMessengerClient,CMessengerBuffer>::OpenLuaStates)
.def("OpenLuaScript", &CMessengerServer<CMessengerClient,CMessengerBuffer>::OpenLuaScript)
.def("GetNextId", &CMessengerServer<CMessengerClient,CMessengerBuffer>::GetNextId)
.def("AddClient", &CMessengerServer<CMessengerClient,CMessengerBuffer>::AddClient)
.def("SendToAll", &CMessengerServer<CMessengerClient,CMessengerBuffer>::SendToAll)
.def("SendToAllBut", &CMessengerServer<CMessengerClient,CMessengerBuffer>::SendToAllBut)
.def("SendTo", &CMessengerServer<CMessengerClient,CMessengerBuffer>::SendTo)
.def("Remove", &CMessengerServer<CMessengerClient,CMessengerBuffer>::Remove)
.def("ToClientType", &CMessengerServer<CMessengerClient,CMessengerBuffer>::ToClientType)
.def("ToBufferType", &CMessengerServer<CMessengerClient,CMessengerBuffer>::ToBufferType)
];

module(s)
[
def("GetServer", &GetServer),
def("ToInt",&ToInt)
];

return s;
}




As you can see, I'm binding it as any of my other classes.

When I try to do this:

function OnAccept(client,buffer,bytes,tn)
teste=CMessengerClient()
print(teste:GetId())
end
Crashes: "Trying to use an unregistered type"

But when I do this:

function OnAccept(client,buffer,bytes,tn)
teste=CMessengerBuffer(1024)
print(teste:GetBytesToSend())
end

Works!

I really don't understand. Both classes are been bound exactly the same way.

Please, I need some help here. I'm completely lost.

Share this post


Link to post
Share on other sites
Can you reduce this to a minimal (and complete) test case? AFAICT, the code looks correct and should work.

Share this post


Link to post
Share on other sites
Sure, I Will do It. But I'm feeling it will work in the test, but i will try hard for it not work. I will do it as soon as I Get home.

Share this post


Link to post
Share on other sites
There are some unit test which come with Luabind. Have you tried running them and do they all pass?

-ddn

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!