我正在使用 Ryan Pavlik 的主发行版中的 luabind 0.9.1 和 Lua 5.1、Win XP SP3 上的 cygwin + 最新补丁 x86、boost 1.48、gcc 4.3.4。Lua 和 boost 是 cygwin 预编译的版本。
我已经成功地在静态和共享版本中构建了 luabind。
两个版本都通过了所有测试,除了在两个版本中都失败的 test_object_identity.cpp 测试。
我已将问题追查到以下问题:如果表中的条目是为 NON 内置类(即不是 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!(实际上,它似乎是零)
但是,如果我使用 iterate 遍历 tabc 条目,则有两个条目具有正确的键/值对。
有任何想法吗?
顺便说一句,像这样重载 == 运算符:
#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 每次使用复杂值作为键时都会创建一个 NEW DISTINCT 对象(但如果您使用原始值或对象则不会)。
这是一个小测试用例来证明这一点:
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,然后在通过 key 对象访问时被 7 覆盖。但是,当通过 tp 再次访问时,会创建一个新条目。这就是 gettable() 随后失败的原因。
谢谢,大卫