Domanda

=== EDIT ===

Il problema è in realtà molto più semplice di questo, qualsiasi funzione avvolta che prende una tabella sta causando il problema. Se avvolgo una funzione che prende Luabind :: Oggetto e chiamo quella funzione con un argomento della tabella, allora il GC provoca un libero non valido (). Sto iniziando a pensare che questa potrebbe essere una sorta di folle problema di compilazione/collegamento, poiché il mio Luabind Dylib compilato contiene simboli Lua (risultando in due copie di quei simboli, uno in quella biblioteca e uno nel mio binario). Forse ho duplicati di alcune variabili statiche LUA o qualcosa del genere? Potrei solo afferrare le cannucce qui.

=== EDIT ===

Utilizzando Luabind 0.9 e GCC 4.2.1 su Mac OS X 10.6

Vedo cosa potrebbe (forse?) Essere un problema con l'utilizzo di Default_Converter dalle tabelle LUA.

Sto cercando di definire i convertitori per vari tipi di elenco nel mio codice, in particolare std :: vector. Quando passerò una tabella a un metodo C ++ con un tale DEFAULT_CONVERTER, LUA si blocca con Free () su un puntatore non valido non appena viene chiamato il collettore della spazzatura.

Probabilmente mi manca qualcosa di semplice qui, ma non riesco a capirlo.

Grazie!

* Codice lua *


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

* Codice C ++ *


#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;
}
È stato utile?

Soluzione

Sì, l'ho capito. Si scopre che Luabind non ha avuto problemi, tranne per il modo in cui è stato costruito. Il sistema di build jam, su Mac OS X, fa sì che la libreria statica LUA sia collegata alla libreria condivisa di Luabind, causando simboli duplicati (e variabili statiche duplicate) quando collego il mio binario finale. Non aveva il tutto La biblioteca Lua collegata, quindi devi ancora collegare di nuovo Liblua.a.

Prendi questa spiegazione con un granello di sale, ma è la mia ipotesi migliore; Non sono un esperto di come funziona il linker Mac OS X. So che quando ho costruito Luabind staticamente, tutto funziona bene.

Quindi, per chiunque costruisca Lubabind in Mac, costruisci staticamente. Ci sono anche altri problemi con la LIB condivisa costruita in jam che dovresti correggere, come il fatto che @Executable_Path è sbagliato. La costruzione statica era morta semplice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top