📄 intrusive_ptr.cpp.svn-base
字号:
#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 = lua_open(); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -