Advertisement

Remove an object from the lua state! Click to flag this post

Started by August 02, 2011 04:01 AM
3 comments, last by sympaval 13 years, 4 months ago
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. Thanks a lot for helping me.

C++ 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
I am not too familiar with Luabind's policies yet I would look at adopt, it depends on how the data is stored internally by Luabind but you could (this sounds like the wrong solution here) just nil the entry in Lua.

By the way why does your thread title contain "Click to flag this post"?
Advertisement
Hi!

I tried by insert element in a weak table and nil them in lua, but it doesn't work. For my thread, I don't know why that appear in the title.

The title of my post is "Replying to Remove an object from the lua state!", then can this additionnal statement be removed from the title? I don't know how to edit the title.

Thanks.
Hi!

I've tried now with luabind adopt policies:

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.
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.

Let's keep in touch.

This topic is closed to new replies.

Advertisement