text: #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;
  }
  
  