Re: Possible problem with default_converter and tables

Catherine West <[email protected]>
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <[email protected]>
Okay, I figured it out.  Turns out the problem I was describing was way more fundamental... any parameter that was passed by lua into c++ and was a table, was causing the gc to fail later.  Really had nothing to do with default_converter.

The problem was actually compilation related.  I'm compiling this on Mac OS X, and compiling a shared library (the default) seems to act a little funny.  I looked at the symbol table for the final shared library, and it included parts of the static lua library (I don't know if this is normal).  This, in the way I was compiling, would have resulted in duplicate symbols from liblua.a in my final binary.  I suspect that this was causing duplicate per-dylib static variables (or something) that were confusing lua itself.

Take this explanation with a huge grain of salt, though; I'm not an expert.  What I do know, is that when I recompiled luabind as a static library, my problem disappeared.  Sorry for cluttering the list with unrelated problems :)

One other thing... compiling the shared library variant of luabind in Mac OS X yields another irritating problem.  For example, the @executable_path dylib symbol is incorrect in the finaly libluabind.dylib, and you have to change it to ../Frameworks/libluabind.dylib with install_name_tool in order to build an app directory correctly.  (I'm not sure if this is fixable, or even an error.  I'm not an expert)  Might it be possible to set the default target for the darwin toolset to build the static version of luabind, or at least say something about it in the documentation?  The static version of the library seems to work great, and is dead simple.

Thanks!

On Feb 6, 2010, at 7:33 PM, Catherine West wrote:

> Using luabind 0.9 and gcc 4.2.1 on mac os x 10.6
> 
> I'm seeing what could (maybe?) be a problem with using a default_converter from lua tables.
> 
> I'm trying to define converters for various list-like types in my code, specifically std::vector.  When I pass a table to a c++ method with such a default_converter, lua crashes with free() on an invalid pointer as soon as the garbage collector is called.
> 
> I'm probably missing something simple here, but I can't figure it out.
> 
> Keep in mind that this is my first project with either lua or luabind, please be gentile if I'm missing something obvious :)
> 
> Thank you!
> 
> *** Lua Code ***
> 
> function first ()
>  -- Doesn't crash
>  -- t = TestClass(1, 3)
> 
>  -- Crashes
>  t = TestClass({1, 2, 3})
> 
>  print(t:get(0))
>  print(t:get(1))
>  print(t:get(2))
> end
> 
> function second ()
>  print("About to call collectgarbage...")
>  collectgarbage()
>  print("Done calling collectgarbage!")
> end
> 
> function test ()
>  first()
>  second()
> end
> 
> *** C++ Code ***
> 
> #include <iostream>
> #include <lua.hpp>
> 
> #include <luabind/luabind.hpp>
> #include <luabind/operator.hpp>
> 
> using namespace std;
> using namespace luabind;
> 
> namespace luabind {
>  template<typename ListType>
>  struct default_converter<std::vector<ListType> > : native_converter_base<std::vector<ListType> > {
>    static int compute_score(lua_State* L, int index) {
>      return lua_type(L, index) == LUA_TTABLE ? 0 : -1;
>    }
> 
>    std::vector<ListType> from(lua_State* L, int index) {
>      std::vector<ListType> list;
>      for (luabind::iterator i(luabind::object(luabind::from_stack(L, index))), end; i != end; ++i)
>        list.push_back(luabind::object_cast<ListType>(*i));
> 
>      return list;
>    }
> 
>    void to(lua_State* L, const std::vector<ListType>& l) {
>      luabind::object list = luabind::newtable(L);
>      for (size_t i = 0; i < l.size(); ++i)
>        list[i+1] = l[i];
> 
>      list.push(L);
>    }
>  };
> }
> 
> class TestClass {
> public:
>  TestClass(std::vector<int> v) : m_vec(v) {}
> 
>  TestClass(int b, int e) {
>    for (int i = b; i <= e; ++i)
>      m_vec.push_back(i);
>  }
> 
>  int get(size_t i) const {
>    return m_vec[i];
>  }
> 
> private:
>  std::vector<int> m_vec;
> };
> 
> int main(int argc, char** argv) {
>  if (argc != 2) {
>    cout << "usage: " << argv[0] << " <scriptname>" << endl;
>    return -1;
>  }
> 
>  std::string scriptName = argv[1];
>  lua_State* L = (lua_State*) lua_open();
>  luaL_openlibs(L);
> 
>  open(L);
> 
>  module(L)
>  [
>    class_<TestClass>("TestClass")
>      .def(constructor<std::vector<int> >())
>      .def(constructor<int, int>())
>      .def("get", &TestClass::get)
>  ];
> 
>  if (luaL_loadfile(L, scriptName.c_str()) || lua_pcall(L, 0, 0, 0)) {
>    cout << "Script error: " << lua_tostring(L, -1) << endl;
>    return -1;
>  }
> 
>  call_function<void>(globals(L)["test"]);
> 
>  lua_close(L);
>  return 0;
> }


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.