Re: [luabind] passing an pointer of an object instance created in c++ for a class bound using luabi
Brought to you by:
arvidn,
daniel_wallin
From: Kariem m. a. f. <kar...@gm...> - 2009-01-25 21:05:54
|
Also i want to make use the stack mechanism of lua because i need to make a dynamic function call so i designed it using the push mechanism, Again what i need: C++: Class1 * class = ClassFactory::getInstance()->createInstance("Class1"); lua_getfield(m_LuaState,-1,this->m_funcname.c_str()); if(lua_isfunction(m_LuaState,-1)) { push(class); pcall....; } in Lua: function Func(obj) obj:move() end Thanks On Sun, Jan 25, 2009 at 10:39 PM, Kariem mohmed abdel fattah < kar...@gm...> wrote: > Thanks very much for your quick replay, the information you provided is > really very helpful. > But what i need if the object is created in the c++ side how to pass its > pointer or reference or even copy it to the lua function. > Thanks > > On Sun, Jan 25, 2009 at 5:01 PM, Tom McCubbin <tom...@gm...>wrote: > >> Kariem, >> >> Assuming you have bound the class, and the module is loaded and >> bootstrapped in the lua_State vm, this is perfectly legal and works great. >> I do it all the time. >> >> The thing you need to think about is how you get a hold of the function >> you want to call. Here is a small sample from a project that extends some >> trading infrastructure in c++ into lua for fast trading model testing... >> >> // this is just normal luabind stuff registering the market (c++) class >> in lua >> // and is how from lua people request a market data subscription ( an >> async stream of realtime equity quotes ) >> luabind::scope >> register_market() >> { >> >> using namespace trd; >> return lb::class_<trd::market>("market") >> .def( "get_market_data_subscription", & >> market::get_market_data_subscription ) >> .property( "current_time", & market::get_current_time ) >> ; >> } >> >> ... >> // here we register an extra class written just to handle callbacks into >> lua for market_data_subscriptions >> // its definition follows >> lb::class_<market_data_subscription_watch>( >> "market_data_subscription_watch" ) >> .def( lb::constructor<trd::market_data_subscription &,lb::object>() ); >> >> // this class adapts a sigc++ callback with quote information to reach >> into lua land >> // to a user defined callback >> class market_data_subscription_watch : public sigc::trackable >> { >> public: >> >> // it takes the c++ mkt data subsr. and a lua table where the key >> 'quote' points to a lua function >> // that takes one argument, quote object (also registered w/ luabind >> but not shown here) >> market_data_subscription_watch( market_data_subscription &sub, object >> table ) : m_lua_state( table.interpreter() ) >> { >> >> // you need to make sure the table passed from lua isnt garbage >> collected and we can't keep refs for it >> // so i place the table in our registry over the next several lines >> lua_pushlightuserdata( m_lua_state, m_lua_state ); // the ptr to >> our lua state will be the index of our ref table >> lua_rawget( m_lua_state, LUA_REGISTRYINDEX ); // now the registry >> table for our module is on top of stack >> >> lua_pushlightuserdata( m_lua_state, this ); // we will put our >> stuff indexed by the ptr to this :) >> table.push( m_lua_state ); // push the table for our callbacks so >> lua won't gc the mfsob! >> lua_rawset( m_lua_state, -3 ); // now set the value in our fing >> table >> >> // this is just sigc++ stuff to have our c++ handle_quote( ) called >> when a quote arrives >> sub.signal_quote().connect( sigc::mem_fun( this, & >> market_data_subscription_watch::handle_quote ) ); >> } >> ~market_data_subscription_watch() >> { >> // clean up of the mds requires releasing refs to the table so it >> can be gc'd as needed >> lua_pushlightuserdata( m_lua_state, m_lua_state ); // the ptr to >> our lua state will be the index of our ref table >> lua_rawget( m_lua_state, LUA_REGISTRYINDEX ); // now the registry >> table for our module is on top of stack >> >> lua_pushlightuserdata( m_lua_state, this ); // we will put our >> stuff indexed by the ptr to this :) >> lua_pushnil( m_lua_state ); // nil out the entry >> lua_rawset( m_lua_state, -3 ); >> } >> >> void >> handle_quote( const quote &q ) >> { >> // the next several lines retrieve our lua table >> lua_pushlightuserdata( m_lua_state, m_lua_state ); // the ptr to >> our lua state will be the index of our ref table >> lua_rawget( m_lua_state, LUA_REGISTRYINDEX ); // now the registry >> table for our module is on top of stack >> >> lua_pushlightuserdata( m_lua_state, this ); // we will put our >> stuff indexed by the ptr to this :) >> lua_rawget( m_lua_state, -2 ); >> >> // now the table passed into the constructor is retrieved >> object m_table( from_stack( m_lua_state, -1 ) ); >> >> // sanity check to make sure it actually was a table >> if ( type( m_table ) == LUA_TTABLE ) >> { >> // here i retireve the lua function from the table >> object func = m_table["quote"]; >> >> // sanity check...make sure it is a function >> if ( type(func) == LUA_TFUNCTION ) >> { >> finally call the lua function passing the quote >> try { >> func( &q ); >> } catch ( const luabind::error &e ) { >> luabind::object err( luabind::from_stack( e.state(), -1 ) ); >> TDEBUG( ACE_TEXT( "market_data_subscription_watch::handle_quote >> failed: %s\n"), luabind::object_cast<const char *>( err ) ); >> } catch ( const std::runtime_error &e ) { >> TDEBUG( ACE_TEXT( "market_data_subscription_watch::handle_quote >> failed: %s\n"), e.what() ); >> } catch ( ... ) { } >> } >> } >> } >> >> protected: >> lua_State * m_lua_state; >> >> }; >> >> >> From lua you have something like this: >> >> -- some lua callback function that gets quotes >> function my_quote_callback( quote ) >> print (string.format( "WE HAVE QUOTE: %4.2f - %4.2f", quote.bid, >> quote.ask ) ) >> end >> >> ... >> -- somewhere else in the code >> -- assuming you have model already and is a luabind model object >> mds = model:get_market_data_subscription( "JDSU" ); >> watch = market_data_subscription_watch( mds, { quote = my_quote_callback } >> ); >> >> Now whenever a quote comes in, my_quote_callback will be called and as you >> see in that function, it can happily access the quote objects properties, >> methods, etc... >> >> Hope this helps and wasn't too much...I was too lazy to write a stripped >> down version. Feel free to post more ?'s if you need. >> >> -tom >> >> On Sun, Jan 25, 2009 at 8:31 AM, Kariem mohmed abdel fattah < >> kar...@gm...> wrote: >> >>> Hi all, >>> I want to know if possible to call a lua function using lua_pcall and >>> lua's stack but passing to that function a pointer to an object of luabind >>> bound class, and be able to call the bound methods on that object from lua >>> function. >>> >>> >>> c++: >>> push(something); >>> lua_pcall(L,1,0,0); >>> >>> lua: >>> function testFunc(pointer) >>> pointer:someBoundMethod() >>> end >>> >>> Thanks >>> >>> -- >>> Kariem >>> >>> >>> ------------------------------------------------------------------------------ >>> This SF.net email is sponsored by: >>> SourcForge Community >>> SourceForge wants to tell your story. >>> http://p.sf.net/sfu/sf-spreadtheword >>> _______________________________________________ >>> luabind-user mailing list >>> lua...@li... >>> https://lists.sourceforge.net/lists/listinfo/luabind-user >>> >>> >> >> >> ------------------------------------------------------------------------------ >> This SF.net email is sponsored by: >> SourcForge Community >> SourceForge wants to tell your story. >> http://p.sf.net/sfu/sf-spreadtheword >> _______________________________________________ >> luabind-user mailing list >> lua...@li... >> https://lists.sourceforge.net/lists/listinfo/luabind-user >> >> > > > -- > Kariem > -- Kariem |