Remove an object from the lua state!

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Remove an object from the lua state!

Sympaval
This post was updated on .
Hi all!

I a  problem since two days now, while integreting lua to C++. I look at all message corresponding to that issue here, but the answers are not clearly explaned to help me, and here I would like to get the ritght way to achieve what I would like to do.

In fact I have a c++ class wraped with luabind and exported to lua. I would like to be able to create a new instance of my class in lua, get it and delete it from c++.
Actually i can create new instances of my object, and delete them without problem, but when I close the lua state with lua_close(myLuaState), the programme segfault. When i comment thje lua_close function all thinks are ok. I realise that it's beacause when the lua_close is called, it tries to call the destructor of all objects in the  lua state.
Then I would like to delete the object from the c++ side when i want, and remove it from the lua state. How can i achieve that?
This question has been already posted here in another way, but i didn't find a answer which solve my problem.
I read the programming in lua documentation but I do not see how to proceed.
This is my code.

extern "C" {
#include <lua.h>
}

#include <iostream>
#include <lua.hpp>
#include <luabind.hpp>
#include <stdio.h>

class Enemy {
private:
  std::string name;

public:
  Enemy(const std::string& n)
    : name(n)
  {
    std::cout << "New enemy born with name : " << name << ".\n";
  }

  Enemy(Enemy const & other)
    : name(other.name)
  {
    std::cout << "Copy of enemy made : " << other.name << ".\n";
  }

  const std::string& getName() const
  {
    std::cout << "Enamy name has been asked and given.\n";
    return name;
  }

  void setName(const std::string& n) {
    name = n;
  }

  virtual int update()
  {
    std::cout << "Enemy::update() called.\n";
    return (43);
  }
};

class EnemyWrapper : public Enemy, public luabind::wrap_base {
public:
  EnemyWrapper(const std::string& n)
    : Enemy(n) {
  }

  virtual int update() {
    return (call<int>("update"));
  }
}

Enemy * CreateEnemy(std::string const & name)                                                                                                                                            
{
  return new Enemy(name);
}


int main() {                                                                                                                                                      
lua_State *  L = lua_open()                                                                                                                                            
  luabind::open(L);
  luaL_openlibs(L);
                                                                                                                                               
  luabind::module(L) [
                      luabind::class_<Enemy, EnemyWrapper>("Enemy")
                      .def(luabind::constructor<const std::string&>())
                      .property("name", &Enemy::getName, &Enemy::setName)
                      .def("update", &Enemy::update, &EnemyWrapper::default_update)
                      .def("CreateEnemy", &CreateEnemy)
                      ];
                                                                                                                                               
  if (luaL_dofile(L, "wrapping.lua") != 0)
    std::cout << lua_tostring(L, -1) << std::endl;                                                                                                          
  int i = 1;
  for (; i <= 10; ++i)
    {
      std::cout << i << " " ;
      Enemy * e = luabind::call_function<Enemy *>(L, "CreateEnemy", "toto");                                                                  
      printf("%p :", e);
      std::cout << e->update() << std::endl;
      sleep(1);
      delete e;
    }
  lua_close(L);
}

Lua code:
print("Start the  script");
                                                                                                                                       
class 'Zombie' (Enemy)

function Zombie:__init(name)
   Enemy.__init(self, name);
end

function Zombie:update()
   print('Zombie:update() called.');
   self.talk();
   return (72);
end

function Zombie:talk()
   print("Yeah I'm a monster");
end

function CreateEnemy(name)            
return(Zombie(name));
end








Reply | Threaded
Open this post in threaded view
|

Re: Re move an object from the lua state!

Teto
I am not sure but I would say allocate your enemy from C++ side with a
factory for example instead of using luabind bound constructor. The
moment you call Enemy.__init(self, name); you create something lua
will collect on lua_close.
Plus you override your C++ function "Enemy * CreateEnemy(std::string
const & name)" by creating a lua one "function CreateEnemy(name)".

when you do  "delete e;" I would say you delete from C++ memory
allocated by lua via "return(Zombie(name));". When you call lua_close,
lua still has references towards that zombie and tries to delete it
despite you've already deleted it ?
I may be wrong but that's how I see it.

Some posts that might interest you:
http://lua-list.2524044.n2.nabble.com/Lunar-C-and-premature-object-destruction-td3193945.html
http://stackoverflow.com/questions/1047212/detecting-stale-c-references-in-lua



On Tue, Aug 2, 2011 at 6:37 AM, Sympaval <[hidden email]> wrote:

>
> Hi all!
>
> I a  problem since two days now, while integreting lua to C++. I look at all
> message corresponding to that issue here, but the answers are not clearly
> explaned to help me, and here I would like to get the ritght way to achieve
> what I would like to do.
>
> In fact I have a c++ class wraped with luabind and exported to lua. I would
> like to be able to create a new instance of my class in lua, get it and
> delete it from c++.
> Actually i can create new instances of my object, and delete them without
> problem, but when I close the lua state with lua_close(myLuaState), the
> programme segfault. When i comment thje lua_close function all thinks are
> ok. I realise that it's beacause when the lua_close is called, it tries to
> call the destructor of all objects in the  lua state.
> Then I would like to delete the object from the c++ side when i want, and
> remove it from the lua state. How can i achieve that?
> This question has been already posted here in another way, but i didn't find
> a answer which solve my problem.
> I read the programming in lua documentation but I do not see how to proceed.
> This is my code.
>
> extern "C" {
> #include <lua.h>
> }
>
> #include <iostream>
> #include <lua.hpp>
> #include <luabind.hpp>
> #include <stdio.h>
>
> class Enemy {
> private:
>  std::string name;
>
> public:
>  Enemy(const std::string& n)
>    : name(n)
>  {
>    std::cout << "New enemy born with name : " << name << ".\n";
>  }
>
>  Enemy(Enemy const & other)
>    : name(other.name)
>  {
>    std::cout << "Copy of enemy made : " << other.name << ".\n";
>  }
>
>  const std::string& getName() const
>  {
>    std::cout << "Enamy name has been asked and given.\n";
>    return name;
>  }
>
>  void setName(const std::string& n) {
>    name = n;
>  }
>
>  virtual int update()
>  {
>    std::cout << "Enemy::update() called.\n";
>    return (43);
>  }
> };
>
> class EnemyWrapper : public Enemy, public luabind::wrap_base {
> public:
>  EnemyWrapper(const std::string& n)
>    : Enemy(n) {
>  }
>
>  virtual int update() {
>    return (call<int>("update"));
>  }
> }
>
> Enemy * CreateEnemy(std::string const & name)
> {
>  return new Enemy(name);
> }
>
>
> int main() {
> lua_State *  L = lua_open()
>  luabind::open(L);
>  luaL_openlibs(L);
>
>  luabind::module(L) [
>                      luabind::class_<Enemy, EnemyWrapper>("Enemy")
>                      .def(luabind::constructor<const std::string&>())
>                      .property("name", &Enemy::getName, &Enemy::setName)
>                      .def("update", &Enemy::update,
> &EnemyWrapper::default_update)
>                      .def("CreateEnemy", &CreateEnemy)
>                      ];
>
>  if (luaL_dofile(L, "wrapping.lua") != 0)
>    std::cout << lua_tostring(L, -1) << std::endl;
>  int i = 1;
>  for (; i <= 10; ++i)
>    {
>      std::cout << i << " " ;
>      Enemy * e = luabind::call_function<Enemy *>(L, "CreateEnemy", "toto");
>      printf("%p :", e);
>      std::cout << e->update() << std::endl;
>      sleep(1);
>      delete e;
>    }
>  lua_close(L);
> }
>
> Lua code:
> print("Start the  script");
>
> class 'Zombie' (Enemy)
>
> function Zombie:__init(name)
>   Enemy.__init(self, name);
> end
>
> function Zombie:update()
>   print('Zombie:update() called.');
>   self.talk();
>   return (72);
> end
>
> function Zombie:talk()
>   print("Yeah I'm a monster");
> end
>
> function CreateEnemy(name)
> return(Zombie(name));
> end
>
>
>
>
>
>
>
>
>
> --
> View this message in context: http://old.nabble.com/Remove-an-object-from-the-lua-state%21-tp32174811p32174811.html
> Sent from the Lua C++ Bind mailing list archive at Nabble.com.
>
>
> ------------------------------------------------------------------------------
> BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
> The must-attend event for mobile developers. Connect with experts.
> Get tools for creating Super Apps. See the latest technologies.
> Sessions, hands-on labs, demos & much more. Register early & save!
> http://p.sf.net/sfu/rim-blackberry-1
> _______________________________________________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user
>

------------------------------------------------------------------------------
BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Re move an object from the lua state!

Andreas Grob-4
In reply to this post by Sympaval
Hi,

if you really want to transfer ownership from lua to c++, you can use
the adopt policy.
There is an example in the documentation:
http://www.rasterbar.com/products/luabind/docs.html#adopt

Regards,
Andreas

Am 02.08.2011 06:37, schrieb Sympaval:

> Hi all!
>
> I a  problem since two days now, while integreting lua to C++. I look at all
> message corresponding to that issue here, but the answers are not clearly
> explaned to help me, and here I would like to get the ritght way to achieve
> what I would like to do.
>
> In fact I have a c++ class wraped with luabind and exported to lua. I would
> like to be able to create a new instance of my class in lua, get it and
> delete it from c++.
> Actually i can create new instances of my object, and delete them without
> problem, but when I close the lua state with lua_close(myLuaState), the
> programme segfault. When i comment thje lua_close function all thinks are
> ok. I realise that it's beacause when the lua_close is called, it tries to
> call the destructor of all objects in the  lua state.
> Then I would like to delete the object from the c++ side when i want, and
> remove it from the lua state. How can i achieve that?
> This question has been already posted here in another way, but i didn't find
> a answer which solve my problem.
> I read the programming in lua documentation but I do not see how to proceed.
> This is my code.
>
> extern "C" {
> #include <lua.h>
> }
>
> #include <iostream>
> #include <lua.hpp>
> #include <luabind.hpp>
> #include <stdio.h>
>
> class Enemy {
> private:
>   std::string name;
>
> public:
>   Enemy(const std::string& n)
>     : name(n)
>   {
>     std::cout << "New enemy born with name : " << name << ".\n";
>   }
>
>   Enemy(Enemy const & other)
>     : name(other.name)
>   {
>     std::cout << "Copy of enemy made : " << other.name << ".\n";
>   }
>
>   const std::string& getName() const
>   {
>     std::cout << "Enamy name has been asked and given.\n";
>     return name;
>   }
>
>   void setName(const std::string& n) {
>     name = n;
>   }
>
>   virtual int update()
>   {
>     std::cout << "Enemy::update() called.\n";
>     return (43);
>   }
> };
>
> class EnemyWrapper : public Enemy, public luabind::wrap_base {
> public:
>   EnemyWrapper(const std::string& n)
>     : Enemy(n) {
>   }
>
>   virtual int update() {
>     return (call<int>("update"));
>   }
> }
>
> Enemy * CreateEnemy(std::string const & name)                                                                                                                                            
> {
>   return new Enemy(name);
> }
>
>
> int main() {                                                                                                                                                      
> lua_State *  L = lua_open()                                                                                                                                            
>   luabind::open(L);
>   luaL_openlibs(L);
>                                                                                                                                                
>   luabind::module(L) [
>                       luabind::class_<Enemy, EnemyWrapper>("Enemy")
>                       .def(luabind::constructor<const std::string&>())
>                       .property("name", &Enemy::getName, &Enemy::setName)
>                       .def("update", &Enemy::update,
> &EnemyWrapper::default_update)
>                       .def("CreateEnemy", &CreateEnemy)
>                       ];
>                                                                                                                                                
>   if (luaL_dofile(L, "wrapping.lua") != 0)
>     std::cout << lua_tostring(L, -1) << std::endl;                                                                                                          
>   int i = 1;
>   for (; i <= 10; ++i)
>     {
>       std::cout << i << " " ;
>       Enemy * e = luabind::call_function<Enemy *>(L, "CreateEnemy", "toto");                                                                  
>       printf("%p :", e);
>       std::cout << e->update() << std::endl;
>       sleep(1);
>       delete e;
>     }
>   lua_close(L);
> }
>
> Lua code:
> print("Start the  script");
>                                                                                                                                        
> class 'Zombie' (Enemy)
>
> function Zombie:__init(name)
>    Enemy.__init(self, name);
> end
>
> function Zombie:update()
>    print('Zombie:update() called.');
>    self.talk();
>    return (72);
> end
>
> function Zombie:talk()
>    print("Yeah I'm a monster");
> end
>
> function CreateEnemy(name)            
> return(Zombie(name));
> end
>
>
>
>
>
>
>
>
>


------------------------------------------------------------------------------
BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user

smime.p7s (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re move an object from the lua state!

Sympaval
Hi Andreas!

I first try to insert my instances in a table, and nil them in lua to prevent lua_close from calling the destructor., but it didn't work.

Now I try with the method you proposed.
When I use  .def("CreateEnemy", &CreateEnemy, luabind::adopt(luabind::result)), the programcompiles but the lua_close function still cause a segfault, i.e notthing changed.

When I use  .def("CreateEnemy", &CreateEnemy, luabind::adopt(_1)), T get this error at the compilation :

(ngonta_e@mid-r02p04 916)g++ wrapping.cpp -o test -llua -lluabind > see.text
In file included from /usr/include/luabind/detail/call.hpp:240,
                 from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/boost/preprocessor/iteration/detail/local.hpp: In function ‘int luabind::detail::invoke_normal(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, mpl_::long_<1l>, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’:
/usr/include/luabind/detail/call.hpp:89:   instantiated from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>, IsVoid = boost::is_void<Enemy*>]’
/usr/include/luabind/detail/call.hpp:101:   instantiated from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:63:   instantiated from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:36:   instantiated from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:111:   instantiated from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/class.hpp:311:   instantiated from ‘void luabind::detail::memfun_registration<Class, F, Policies>::register_(lua_State*) const [with Class = Enemy, F = Enemy* (*)(const std::string&), Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
wrapping.cpp:110:   instantiated from here
/usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘consumed_args’
In file included from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/luabind/detail/call.hpp:257: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘match’
/usr/include/luabind/detail/call.hpp:89:   instantiated from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>, IsVoid = boost::is_void<Enemy*>]’
/usr/include/luabind/detail/call.hpp:101:   instantiated from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:63:   instantiated from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:36:   instantiated from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:111:   instantiated from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/class.hpp:311:   instantiated from ‘void luabind::detail::memfun_registration<Class, F, Policies>::register_(lua_State*) const [with Class = Enemy, F = Enemy* (*)(const std::string&), Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
wrapping.cpp:110:   instantiated from here
/usr/include/luabind/detail/call.hpp:283: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘apply’
In file included from /usr/include/luabind/detail/call.hpp:305,
                 from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘converter_postcall’

Please, reagarging my issue, what should i do in oder, to instanciate a new enemy wich will use the update methode in lua script, and delete the instance from c++ when it become useless for me, without having a crash in lua_close?

If I should use luabind adopt_policy, what is the right wayin this case? Thank for helping me, I'm sure there should be a solution.
CreateEnemy function is just like an enemies factory, not a member function.

Thanks a lot, I'm really stressed.


Andreas Grob-4 wrote
Hi,

if you really want to transfer ownership from lua to c++, you can use
the adopt policy.
There is an example in the documentation:
http://www.rasterbar.com/products/luabind/docs.html#adopt

Regards,
Andreas

Am 02.08.2011 06:37, schrieb Sympaval:
> Hi all!
>
> I a  problem since two days now, while integreting lua to C++. I look at all
> message corresponding to that issue here, but the answers are not clearly
> explaned to help me, and here I would like to get the ritght way to achieve
> what I would like to do.
>
> In fact I have a c++ class wraped with luabind and exported to lua. I would
> like to be able to create a new instance of my class in lua, get it and
> delete it from c++.
> Actually i can create new instances of my object, and delete them without
> problem, but when I close the lua state with lua_close(myLuaState), the
> programme segfault. When i comment thje lua_close function all thinks are
> ok. I realise that it's beacause when the lua_close is called, it tries to
> call the destructor of all objects in the  lua state.
> Then I would like to delete the object from the c++ side when i want, and
> remove it from the lua state. How can i achieve that?
> This question has been already posted here in another way, but i didn't find
> a answer which solve my problem.
> I read the programming in lua documentation but I do not see how to proceed.
> This is my code.
>
> extern "C" {
> #include <lua.h>
> }
>
> #include <iostream>
> #include <lua.hpp>
> #include <luabind.hpp>
> #include <stdio.h>
>
> class Enemy {
> private:
>   std::string name;
>
> public:
>   Enemy(const std::string& n)
>     : name(n)
>   {
>     std::cout << "New enemy born with name : " << name << ".\n";
>   }
>
>   Enemy(Enemy const & other)
>     : name(other.name)
>   {
>     std::cout << "Copy of enemy made : " << other.name << ".\n";
>   }
>
>   const std::string& getName() const
>   {
>     std::cout << "Enamy name has been asked and given.\n";
>     return name;
>   }
>
>   void setName(const std::string& n) {
>     name = n;
>   }
>
>   virtual int update()
>   {
>     std::cout << "Enemy::update() called.\n";
>     return (43);
>   }
> };
>
> class EnemyWrapper : public Enemy, public luabind::wrap_base {
> public:
>   EnemyWrapper(const std::string& n)
>     : Enemy(n) {
>   }
>
>   virtual int update() {
>     return (call<int>("update"));
>   }
> }
>
> Enemy * CreateEnemy(std::string const & name)                                                                                                                                            
> {
>   return new Enemy(name);
> }
>
>
> int main() {                                                                                                                                                      
> lua_State *  L = lua_open()                                                                                                                                            
>   luabind::open(L);
>   luaL_openlibs(L);
>                                                                                                                                                
>   luabind::module(L) [
>                       luabind::class_<Enemy, EnemyWrapper>("Enemy")
>                       .def(luabind::constructor<const std::string&>())
>                       .property("name", &Enemy::getName, &Enemy::setName)
>                       .def("update", &Enemy::update,
> &EnemyWrapper::default_update)
>                       .def("CreateEnemy", &CreateEnemy)
>                       ];
>                                                                                                                                                
>   if (luaL_dofile(L, "wrapping.lua") != 0)
>     std::cout << lua_tostring(L, -1) << std::endl;                                                                                                          
>   int i = 1;
>   for (; i <= 10; ++i)
>     {
>       std::cout << i << " " ;
>       Enemy * e = luabind::call_function<Enemy *>(L, "CreateEnemy", "toto");                                                                  
>       printf("%p :", e);
>       std::cout << e->update() << std::endl;
>       sleep(1);
>       delete e;
>     }
>   lua_close(L);
> }
>
> Lua code:
> print("Start the  script");
>                                                                                                                                        
> class 'Zombie' (Enemy)
>
> function Zombie:__init(name)
>    Enemy.__init(self, name);
> end
>
> function Zombie:update()
>    print('Zombie:update() called.');
>    self.talk();
>    return (72);
> end
>
> function Zombie:talk()
>    print("Yeah I'm a monster");
> end
>
> function CreateEnemy(name)            
> return(Zombie(name));
> end
>
>
>
>
>
>
>
>
>



 
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
luabind-user mailing list
luabind-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Re move an object from the lua state!

Sympaval
Hi!

I managed to reach my aim by using this method :

Enemy * e = luabind::call_function<Enemy *>(L,  "CreateEnemy",  "toto") [luabind::adopt(luabind::result)];

it now works!

I will try now to create enemies anywhere in my code my this method, and see if the programm is stable. I will let you know if things work perfecly.

Thanks for your help.

Sympaval wrote
Hi Andreas!

I first try to insert my instances in a table, and nil them in lua to prevent lua_close from calling the destructor., but it didn't work.

Now I try with the method you proposed.
When I use  .def("CreateEnemy", &CreateEnemy, luabind::adopt(luabind::result)), the programcompiles but the lua_close function still cause a segfault, i.e notthing changed.

When I use  .def("CreateEnemy", &CreateEnemy, luabind::adopt(_1)), T get this error at the compilation :

(ngonta_e@mid-r02p04 916)g++ wrapping.cpp -o test -llua -lluabind > see.text
In file included from /usr/include/luabind/detail/call.hpp:240,
                 from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/boost/preprocessor/iteration/detail/local.hpp: In function ‘int luabind::detail::invoke_normal(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, mpl_::long_<1l>, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’:
/usr/include/luabind/detail/call.hpp:89:   instantiated from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>, IsVoid = boost::is_void<Enemy*>]’
/usr/include/luabind/detail/call.hpp:101:   instantiated from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:63:   instantiated from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:36:   instantiated from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:111:   instantiated from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/class.hpp:311:   instantiated from ‘void luabind::detail::memfun_registration<Class, F, Policies>::register_(lua_State*) const [with Class = Enemy, F = Enemy* (*)(const std::string&), Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
wrapping.cpp:110:   instantiated from here
/usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘consumed_args’
In file included from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/luabind/detail/call.hpp:257: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘match’
/usr/include/luabind/detail/call.hpp:89:   instantiated from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::false_) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>, IsVoid = boost::is_void<Enemy*>]’
/usr/include/luabind/detail/call.hpp:101:   instantiated from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:63:   instantiated from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:36:   instantiated from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/make_function.hpp:111:   instantiated from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = Enemy* (*)(const std::string&), Signature = boost::mpl::vector2<Enemy*, const std::string&>, Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
/usr/include/luabind/class.hpp:311:   instantiated from ‘void luabind::detail::memfun_registration<Class, F, Policies>::register_(lua_State*) const [with Class = Enemy, F = Enemy* (*)(const std::string&), Policies = luabind::detail::policy_cons<luabind::detail::adopt_policy<1>, luabind::detail::null_type>]’
wrapping.cpp:110:   instantiated from here
/usr/include/luabind/detail/call.hpp:283: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘apply’
In file included from /usr/include/luabind/detail/call.hpp:305,
                 from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
                 from /usr/include/luabind/detail/call.hpp:175,
                 from /usr/include/luabind/make_function.hpp:10,
                 from /usr/include/luabind/function.hpp:8,
                 from /usr/include/luabind/class.hpp:94,
                 from /usr/include/luabind.hpp:28,
                 from wrapping.cpp:17:
/usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error: ‘struct luabind::detail::adopt_policy<1>::only_accepts_nonconst_pointers’ has no member named ‘converter_postcall’

Please, reagarging my issue, what should i do in oder, to instanciate a new enemy wich will use the update methode in lua script, and delete the instance from c++ when it become useless for me, without having a crash in lua_close?

If I should use luabind adopt_policy, what is the right wayin this case? Thank for helping me, I'm sure there should be a solution.
CreateEnemy function is just like an enemies factory, not a member function.

Thanks a lot, I'm really stressed.


Andreas Grob-4 wrote
Hi,

if you really want to transfer ownership from lua to c++, you can use
the adopt policy.
There is an example in the documentation:
http://www.rasterbar.com/products/luabind/docs.html#adopt

Regards,
Andreas

Am 02.08.2011 06:37, schrieb Sympaval:
> Hi all!
>
> I a  problem since two days now, while integreting lua to C++. I look at all
> message corresponding to that issue here, but the answers are not clearly
> explaned to help me, and here I would like to get the ritght way to achieve
> what I would like to do.
>
> In fact I have a c++ class wraped with luabind and exported to lua. I would
> like to be able to create a new instance of my class in lua, get it and
> delete it from c++.
> Actually i can create new instances of my object, and delete them without
> problem, but when I close the lua state with lua_close(myLuaState), the
> programme segfault. When i comment thje lua_close function all thinks are
> ok. I realise that it's beacause when the lua_close is called, it tries to
> call the destructor of all objects in the  lua state.
> Then I would like to delete the object from the c++ side when i want, and
> remove it from the lua state. How can i achieve that?
> This question has been already posted here in another way, but i didn't find
> a answer which solve my problem.
> I read the programming in lua documentation but I do not see how to proceed.
> This is my code.
>
> extern "C" {
> #include <lua.h>
> }
>
> #include <iostream>
> #include <lua.hpp>
> #include <luabind.hpp>
> #include <stdio.h>
>
> class Enemy {
> private:
>   std::string name;
>
> public:
>   Enemy(const std::string& n)
>     : name(n)
>   {
>     std::cout << "New enemy born with name : " << name << ".\n";
>   }
>
>   Enemy(Enemy const & other)
>     : name(other.name)
>   {
>     std::cout << "Copy of enemy made : " << other.name << ".\n";
>   }
>
>   const std::string& getName() const
>   {
>     std::cout << "Enamy name has been asked and given.\n";
>     return name;
>   }
>
>   void setName(const std::string& n) {
>     name = n;
>   }
>
>   virtual int update()
>   {
>     std::cout << "Enemy::update() called.\n";
>     return (43);
>   }
> };
>
> class EnemyWrapper : public Enemy, public luabind::wrap_base {
> public:
>   EnemyWrapper(const std::string& n)
>     : Enemy(n) {
>   }
>
>   virtual int update() {
>     return (call<int>("update"));
>   }
> }
>
> Enemy * CreateEnemy(std::string const & name)                                                                                                                                            
> {
>   return new Enemy(name);
> }
>
>
> int main() {                                                                                                                                                      
> lua_State *  L = lua_open()                                                                                                                                            
>   luabind::open(L);
>   luaL_openlibs(L);
>                                                                                                                                                
>   luabind::module(L) [
>                       luabind::class_<Enemy, EnemyWrapper>("Enemy")
>                       .def(luabind::constructor<const std::string&>())
>                       .property("name", &Enemy::getName, &Enemy::setName)
>                       .def("update", &Enemy::update,
> &EnemyWrapper::default_update)
>                       .def("CreateEnemy", &CreateEnemy)
>                       ];
>                                                                                                                                                
>   if (luaL_dofile(L, "wrapping.lua") != 0)
>     std::cout << lua_tostring(L, -1) << std::endl;                                                                                                          
>   int i = 1;
>   for (; i <= 10; ++i)
>     {
>       std::cout << i << " " ;
>       Enemy * e = luabind::call_function<Enemy *>(L, "CreateEnemy", "toto");                                                                  
>       printf("%p :", e);
>       std::cout << e->update() << std::endl;
>       sleep(1);
>       delete e;
>     }
>   lua_close(L);
> }
>
> Lua code:
> print("Start the  script");
>                                                                                                                                        
> class 'Zombie' (Enemy)
>
> function Zombie:__init(name)
>    Enemy.__init(self, name);
> end
>
> function Zombie:update()
>    print('Zombie:update() called.');
>    self.talk();
>    return (72);
> end
>
> function Zombie:talk()
>    print("Yeah I'm a monster");
> end
>
> function CreateEnemy(name)            
> return(Zombie(name));
> end
>
>
>
>
>
>
>
>
>



 
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
luabind-user mailing list
luabind-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/luabind-user