Shared pointers and wrapper base.
Nigel Atkinson <[email protected]>
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <1294744695.5921.31.camel@octavo> |
I had some problems with code hitting an assert, when calling a method, that has been set up to be over-ridden. The objects are being held by shared pointers which in turn where in a list. Basically when an object is created by a script, then a shared pointer is given to C++ land to hold on to, and then the Lua side of things lets go of the object, bad things happen. I've noticed the weak ref held by wrap_base gets clobbered as soon as you do "obj = nil", even BEFORE it is garbage collected! Attached is a small program that demonstrates the problem, and a small patch the fixes it (if you un-comment the code in the example too). There are various other (better?) ways this could be fixed, my patch is basically the path of least resistance. Other ways could be: - Instead of assert, throw an exception. - Provide an "isValid" function. - A "callp" or something that is just like "call", except returns an error code if the weak reference held by wrap_base shows up nil. Different situations call for different behaviour when this happens. Do you ignore it and carry on (perhaps it's destined for deletion next render frame)? Do you just call the default method instead? What does everyone think? Anyone else 'find' this? :-) Nigel Atkinson ------------------------------------------------------------------------------ Gaining the trust of online customers is vital for the success of any company that requires sensitive data to be transmitted over the Web. Learn how to best implement a security strategy that keeps consumers' information secure and instills the confidence they need to proceed with transactions. http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ luabind-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/luabind-user
test.cpp
(text/x-c++src, 1.6 KB)
#include <luabind/luabind.hpp>
#include <lua.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace std;
using namespace luabind;
class test
{
public:
test() { cout << "Hello" << endl; }
virtual ~test() { cout << "Goodbye" << endl; }
virtual void method() { cout << "Method!" << endl; }
};
class test_wrapper : public test, public luabind::wrap_base
{
public:
virtual void method()
{
//lua_State* L = m_self.state();
//m_self.get(L);
//if( ! lua_isnil( L, -1 ) )
call<void>( "method" );
lua_pop( L, 1 );
}
static void default_method( test *ptr )
{
ptr->test::method();
}
};
typedef boost::shared_ptr<test_wrapper> test_ptr;
test_ptr stored_ptr;
void store( test_ptr ptr )
{
stored_ptr = ptr;
}
int main()
{
lua_State *L = lua_open();
luaL_openlibs( L );
open(L);
module(L)
[
class_<test, test_wrapper, test_ptr>("tester")
.def(constructor<>())
.def("method", &test::method, &test_wrapper::default_method ),
def( "store", &store )
];
const char* str =
"print 'Whooppie!'\n"
"t = tester()\n"
"t:method()\n"
"store(t)\n"
"t = nil\n";
if( luaL_dostring(L, str ) )
{
cout << "Error! " << lua_tostring(L,-1) << endl;
}
stored_ptr->method();
lua_gc(L, LUA_GCCOLLECT, 0 );
stored_ptr->method();
stored_ptr.reset(); // un-store before closing lua state.
lua_close(L);
}
0001-Small-change-to-allow-wrapper-code-to-test-for-possi.patch
(text/x-patch, 728 B)
>From 277222d1a9d49d155c058bd507b43569f6ac9af9 Mon Sep 17 00:00:00 2001 From: Nigel Atkinson <[email protected]> Date: Tue, 11 Jan 2011 21:35:08 +1100 Subject: [PATCH] Small change to allow wrapper code to test for possible assert case. --- luabind/wrapper_base.hpp | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/luabind/wrapper_base.hpp b/luabind/wrapper_base.hpp index d54c668..9b64f5b 100755 --- a/luabind/wrapper_base.hpp +++ b/luabind/wrapper_base.hpp @@ -63,7 +63,7 @@ namespace luabind #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/wrapper_base.hpp>, 1)) #include BOOST_PP_ITERATE() - private: + protected: wrapped_self_t m_self; }; -- 1.7.0.4