2

LuabindとC++を使い始めたばかりです。私の目標は非常に単純です。

C ++オブジェクトポインターを引数として取り、オブジェクトをLua変数に格納するLua関数を作成したいと思います。Lua関数が呼び出されるたびに、最初に、Lua関数に渡されたオブジェクトポインターが、前の呼び出し中に保存されたものと同じオブジェクトポインターであるかどうかを確認する必要があります。

完全なコードは次のとおりです。

extern "C" {
  #include "lua.h"
  #include "lualib.h"
}
#include <luabind/luabind.hpp>

class Obj {
};

int main(int argc, char **argv) {
  lua_State* cLuaState = luaL_newstate();
  luabind::open(cLuaState);
  luaL_openlibs(cLuaState);

  luabind::module(cLuaState) [
    luabind::class_<Obj>("Obj")
  ];

  luaL_dostring(cLuaState, "\
    function func(v)\n\
      print (\"Before: x is same as v?\")\n\
      print (x == v)\n\
      x = v\n\
      print (\"After: x is same as v?\")\n\
      print (x == v)\n\
    end");

  Obj* o = new Obj();
  try {
    luabind::call_function<void>(cLuaState, "func", o);
    luabind::call_function<void>(cLuaState, "func", o);
  } catch (std::exception &e) {
    std::cout << "Exception thrown: " << e.what() << std::endl;
    return 1;
  }
  return 0;
}

このプログラムを実行すると、次の出力が表示されると思います。

Before: x is same as v?
false
Setting v
After: x is same as v?
true
Before: x is same as v?
true 
Setting v
After: x is same as v?
true

ただし、プログラムを実行すると、「x」と「v」の比較中にLua関数を2回呼び出したときにクラッシュします。これは、プログラムからの実際の結果の出力です。

Before: x is same as v?
false
Setting v
After: x is same as v?
true
Before: x is same as v?
Exception thrown: lua runtime error
*** Exited with return code: 1 ***

見てわかるように、比較は、「v」が設定される前と後の両方の最初の関数呼び出し中に機能します。ただし、最初の比較は、呼び出された2番目の関数の実行中に失敗します。

私は信じられないほど明白な何かを見逃しているに違いありませんが、それが何であるかを本当に理解することはできません。誰かが私が間違っていることを見ることができますか?どんなアドバイスも大歓迎です!

マーティン、ありがとうございました

4

1 に答える 1

3

私は解決策を見つけました。何らかの理由で、Luaは、ポインター自体の比較を実行するのではなく、オーバーロードされたC++のequals演算子を使用して2つのオブジェクトの比較を実行したいと考えているようです。2つのオブジェクトのアドレスを比較し、それをLuaにバインドするだけのオーバーロードされた等式演算子を作成することで、それを機能させることができます。

Luaが最初の関数呼び出しではなく2番目の関数呼び出しでこの方法でのみ比較を行う理由はまだわかりませんが、少なくとも今では実行可能な解決策があります。

完全に変更された作業バージョンは以下のとおりです。

extern "C" {
  #include "lua.h"
  #include "lualib.h"
}
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>

class Obj {
};

bool operator==(const Obj& a, const Obj& b) {
  return &a == &b;
}

int main(int argc, char **argv) {
  lua_State* cLuaState = luaL_newstate();
  luabind::open(cLuaState);
  luaL_openlibs(cLuaState);

  luabind::module(cLuaState) [
    luabind::class_<Obj>("Obj")
      .def(luabind::const_self == luabind::const_self)
  ];

  luaL_dostring(cLuaState, "\
    function func(v)\n\
      print (\"Before: x is same as v?\")\n\
      print (x == v)\n\
      x = v\n\
      print (\"After: x is same as v?\")\n\
      print (x == v)\n\
    end");

  Obj* o = new Obj();
  try {
    luabind::call_function<void>(cLuaState, "func", o);
    luabind::call_function<void>(cLuaState, "func", o);
  } catch (std::exception &e) {
    std::cout << "Exception thrown: " << e.what() << std::endl;
    return 1;
  }
  return 0;
}
于 2013-02-13T06:49:22.417 に答える