luabind :не может получить значения из таблицы, проиндексированной не -построенной -в классах‏

Я использую luabind 0.9.1 из основного дистрибутива Райана Павлика с Lua 5.1, cygwin на Win XP SP3 + последние патчи x86, boost 1.48, gcc 4.3.4. Lua и boost являются предварительно скомпилированными версиями cygwin -.

Я успешно собрал luabind как в статической, так и в общей версии.

Обе версии проходят все тесты, ЗА ИСКЛЮЧЕНИЕМ теста _object _identity.cpp, который не проходит в обеих версиях.

Я нашел следующую проблему :Если запись в таблице создана для НЕ построенного -в классе (, то есть не int, string и т. д. ), значение НЕ МОЖЕТ быть получено.

Вот фрагмент кода, демонстрирующий, что:

#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] действительно равен 10, а tabc[temp _object] НЕ равен 30! (На самом деле, кажется, что это ноль)

Однако, если я использую итерацию для перехода по записям вкладок, есть две записи с ПРАВИЛЬНЫМИ парами ключ/значение.

Есть идеи?

Кстати, такая перегрузка оператора ==:

#include <luabind/operator.hpp>

struct test_param
{
    int obj;
    bool operator==(test_param const& rhs) const
    {
        return obj == rhs.obj;
    }
};

и

module(L)
    [
        class_<test_param>("test_param")
           .def_readwrite("obj", &test_param::obj)
           .def(const_self == const_self)
    ];

не меняет результат.

Я также пытался переключиться на settable ()и gettable ()с помощью оператора []. Результат тот же. Я вижу с помощью отладчика, что вызывается преобразование ключа по умолчанию, поэтому я предполагаю, что ошибка возникает где-то там, но я не могу понять, в чем именно проблема.

Как показывает следующий простой тестовый пример, в преобразовании Luabind для сложных типов определенно есть ошибка.:

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 
} 

Надеюсь, кто-то умнее меня сможет это понять, Спасибо

Я обнаружил проблему в том факте, что Luabind создает НОВЫЙ ОТЛИЧНЫЙ объект КАЖДЫЙ раз, когда вы используете сложное значение в качестве ключа (, но НЕ делает этого, если вы используете примитивное значение или объект ).

Вот небольшой тестовый пример, который демонстрирует это.:

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";
    }
}

Обратите внимание, как tabc[tp] сначала имеет значение 5, а затем заменяется на 7 при доступе через объект ключа. Однако при СНОВА доступе через tp создается новая запись. Вот почему gettable ()впоследствии дает сбой.

Спасибо, Дэвид

7
задан qwer1304 29 April 2012 в 15:34
поделиться