Estoy usando luabind 0.9.1 de la distribución principal de Ryan Pavlik con Lua 5.1, cygwin en Win XP SP3 + parches más recientes x86, boost 1.48, gcc 4.3.4. Lua y boost son versiones pre compiladas de cygwin.luabind: no se pueden recuperar los valores de la tabla indexada por clases no incorporadas
He creado exitosamente luabind en versiones estáticas y compartidas.
Ambas versiones pasan todas las pruebas EXCEPTO para la prueba test_object_identity.cpp que falla en ambas versiones.
He rastreado el problema hasta el siguiente problema: Si se crea una entrada en una tabla para la clase NON incorporada (es decir, no int, cadena, etc.), el valor NO PUEDE recuperarse.
Aquí es una pieza de código que muestra esto:
#include "test.hpp"
#include <luabind/luabind.hpp>
#include <luabind/detail/debug.hpp>
using namespace luabind;
struct test_param
{
int obj;
};
void test_main(lua_State* L)
{
using namespace luabind;
module(L)
[
class_<test_param>("test_param")
.def_readwrite("obj", &test_param::obj)
];
test_param temp_object;
object tabc = newtable(L);
tabc[1] = 10;
tabc[temp_object] = 30;
TEST_CHECK(tabc[1] == 10); // passes
TEST_CHECK(tabc[temp_object] == 30); // FAILS!!!
}
TABC [1] es, en efecto, mientras que 10 TABC [temp_object] NO es 30! (en realidad, parece ser nil)
Sin embargo, si utilizo iterar para repasar las entradas de tabc, hay dos entradas con los pares clave/valor CORRECT.
¿Alguna idea?
Por cierto, la sobrecarga del operador == así:
#include <luabind/operator.hpp>
struct test_param
{
int obj;
bool operator==(test_param const& rhs) const
{
return obj == rhs.obj;
}
};
y
module(L)
[
class_<test_param>("test_param")
.def_readwrite("obj", &test_param::obj)
.def(const_self == const_self)
];
no cambia el resultado.
También intenté cambiar a settable() y gettable() desde el operador []. El resultado es el mismo. Puedo ver con el depurador que se invoca la conversión predeterminada de la clave, por lo que supongo que el error surge de algún lugar, pero no entiendo cuál es exactamente el problema.
Como el siguiente programa de caso de prueba simple, hay sin duda un error en la conversión de Luabind para este tipo de complejos:
struct test_param : wrap_base
{
int obj;
bool operator==(test_param const& rhs) const
{ return obj == rhs.obj ; }
};
void test_main(lua_State* L)
{
using namespace luabind;
module(L)
[
class_<test_param>("test_param")
.def(constructor<>())
.def_readwrite("obj", &test_param::obj)
.def(const_self == const_self)
];
object tabc, zzk, zzv;
test_param tp, tp1;
tp.obj = 123456;
// create new table
tabc = newtable(L);
// set tabc[tp] = 5;
// o k v
settable(tabc, tp, 5);
// get access to entry through iterator() API
iterator zzi(tabc);
// get the key object
zzk = zzi.key();
// read back the value through gettable() API
// o k
zzv = gettable(tabc, zzk);
// check the entry has the same value
// irrespective of access method
TEST_CHECK (*zzi == 5 &&
object_cast<int>(zzv) == 5);
// convert key to its REAL type (test_param)
tp1 = object_cast<test_param>(zzk);
// check two keys are the same
TEST_CHECK(tp == tp1);
// read the value back from table using REAL key type
zzv = gettable(tabc, tp1);
// check the value
TEST_CHECK(object_cast<int>(zzv) == 5);
// the previous call FAILS with
// Terminated with exception: "unable to make cast"
// this is because gettable() doesn't return
// a TRUE value, but nil instead
}
Con suerte, alguien más inteligente que yo puedo resolver esto, Thx
I He rastreado el problema hasta el hecho de que Luabind crea un objeto NUEVO DISTINTO CADA vez que utilizas un valor complejo como clave (pero NO lo hace si usas uno primitivo o un objeto).
Aquí hay un pequeño caso de prueba que lo demuestra:
struct test_param : wrap_base
{
int obj;
bool operator==(test_param const& rhs) const
{ return obj == rhs.obj ; }
};
void test_main(lua_State* L)
{
using namespace luabind;
module(L)
[
class_<test_param>("test_param")
.def(constructor<>())
.def_readwrite("obj", &test_param::obj)
.def(const_self == const_self)
];
object tabc, zzk, zzv;
test_param tp;
tp.obj = 123456;
tabc = newtable(L);
// o k v
settable(tabc, tp, 5);
iterator zzi(tabc), end;
std::cerr << "value = " << *zzi << "\n";
zzk = zzi.key();
// o k v
settable(tabc, tp, 6);
settable(tabc, zzk, 7);
for (zzi = iterator(tabc); zzi != end; ++zzi)
{
std::cerr << "value = " << *zzi << "\n";
}
}
Observe cómo TABC [tp] primero tiene el valor 5 y luego se sobrescribe con 7 cuando se tiene acceso a través del objeto clave. Sin embargo, cuando se vuelve a acceder a través de tp, se crea una nueva entrada. Es por eso que gettable() falla posteriormente.
Thx, David
¿Alguna vez resolvió este problema? Ya tengo este problema cuando uso valores int como claves para tablas, p. local testTable = {[10] = "verde", [9] = "naranja", [8] = "amarillo"} - si uso cadenas en lugar de números como claves - funciona bien - doy esta tabla como un param a una función de C++ y me sale el error de lanzamiento también – Steve