1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#include <iostream>
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
bool dostring(lua_State* L, const char* str)
{
if (luaL_loadbuffer(L, str, std::strlen(str), str) || lua_pcall(L, 0, 0, 0))
{
const char* a = lua_tostring(L, -1);
std::cout << a << "\n";
lua_pop(L, 1);
return true;
}
return false;
}
#include <luabind/luabind.hpp>
#include <boost/intrusive_ptr.hpp>
namespace luabind
{
namespace converters
{
// tell luabind that there is a converter for boost::intrusive_ptr<T>
template<class T>
yes_t is_user_defined(by_value<boost::intrusive_ptr<T> >);
template<class T>
yes_t is_user_defined(by_const_reference<boost::intrusive_ptr<T> >);
// function used to destruct the object in lua
template<class T>
struct decrement_ref_count
{
static void apply(void* ptr)
{
T* p = static_cast<T*>(ptr);
intrusive_ptr_release(p);
}
};
template<class T>
void convert_cpp_to_lua(lua_State* L, const boost::intrusive_ptr<T>& ptr)
{
if (!ptr)
{
lua_pushnil(L);
return;
}
T* raw_ptr = ptr.get();
// add reference to object, this will be released when the object is collected
intrusive_ptr_add_ref(raw_ptr);
detail::class_registry* registry = luabind::detail::class_registry::get_registry(L);
detail::class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
assert(crep != 0 && "You are trying to convert an unregistered type");
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(detail::object_rep));
// we send 0 as destructor since we know it will never be called
new(obj) luabind::detail::object_rep(raw_ptr, crep, detail::object_rep::owner, decrement_ref_count<T>::apply);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
template<class T>
boost::intrusive_ptr<T>
convert_lua_to_cpp(lua_State* L, by_const_reference<boost::intrusive_ptr<T> >, int index)
{
typename detail::default_policy::template generate_converter<T*, detail::lua_to_cpp>::type converter;
T* ptr = converter.apply(L, LUABIND_DECORATE_TYPE(T*), index);
return boost::intrusive_ptr<T>(ptr);
}
template<class T>
boost::intrusive_ptr<T> convert_lua_to_cpp(lua_State* L, by_value<boost::intrusive_ptr<T> >, int index)
{
return convert_lua_to_cpp(L, by_const_reference<boost::intrusive_ptr<T> >(), index);
}
template<class T>
int match_lua_to_cpp(lua_State* L, by_value<boost::intrusive_ptr<T> >, int index)
{
typedef typename detail::default_policy::template generate_converter<T*, detail::lua_to_cpp>::type converter_t;
return converter_t::match(L, LUABIND_DECORATE_TYPE(T*), index);
}
template<class T>
int match_lua_to_cpp(lua_State* L, by_const_reference<boost::intrusive_ptr<T> >, int index)
{
typedef typename detail::default_policy::template generate_converter<T*, detail::lua_to_cpp>::type converter_t;
return converter_t::match(L, LUABIND_DECORATE_TYPE(T*), index);
}
}
}
struct A
{
A()
: cnt(0)
{}
~A() { std::cout << "free memory\n"; }
int cnt;
};
void intrusive_ptr_add_ref(A* ptr)
{
++ptr->cnt;
std::cout << "add ref\n";
}
void intrusive_ptr_release(A* ptr)
{
--ptr->cnt;
std::cout << "release\n";
if (ptr->cnt == 0) delete ptr;
}
void f(boost::intrusive_ptr<A> ptr)
{
std::cout << "count: " << ptr->cnt << "\n";
}
boost::intrusive_ptr<A> factory()
{
return boost::intrusive_ptr<A>(new A());
}
int main()
{
lua_State* L = luaL_newstate();
lua_baselibopen(L);
luabind::open(L);
using namespace luabind;
module(L)
[
class_<A>("A")
.def_readonly("cnt", &A::cnt),
def("factory", &factory),
def("f", &f)
];
dostring(L, "a = factory()");
dostring(L, "print('lua count: ' .. a.cnt)");
dostring(L, "f(a)");
lua_close(L);
return 0;
}
|