私は、Lua 5.1、Win XP SP3 の cygwin + 最新パッチ x86、ブースト 1.48、gcc 4.3.4 を含む Ryan Pavlik のマスター ディストリビューションの luabind 0.9.1 を使用しています。Lua と boost は cygwin のコンパイル済みバージョンです。
静的バージョンと共有バージョンの両方で luabind のビルドに成功しました。
両方のバージョンで失敗する test_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 ではありません! (実際にはゼロのようです)
ただし、 iterate を使用して tabc エントリを調べると、正しいキーと値のペアを持つ 2 つのエントリがあります。
何か案は?
ところで、次のように == 演算子をオーバーロードします。
#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
}
うまくいけば、私より賢い誰かがこれを理解できるでしょう、Thx
複雑な値をキーとして使用するたびに 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 を持ち、キー オブジェクトを介してアクセスされると 7 で上書きされることに注意してください。ただし、tp を介して AGAIN にアクセスすると、新しいエントリが作成されます。これが、その後 gettable() が失敗する理由です。
Thx、デビッド