简体   繁体   English

有没有办法将 Lua 成员变量绑定为对该变量名称的 C/C++ 函数的调用

[英]Is there a way to bind Lua member variable as a call to C/C++ function with the name of that variable

I'm totally new to Lua.我对 Lua 完全陌生。 From what I understand it is possible to bind Lua variables and methods to ones on the C/C++ side.据我了解,可以将 Lua 变量和方法绑定到 C/C++ 端的变量和方法。

But is it possible to bind a user type variable to the call of the C/C++ function which may look like properties on the Lua side ?但是是否可以将用户类型变量绑定到 C/C++ 函数的调用,它可能看起来像 Lua 端的属性?

Example:例子:

// C++
struct player {
  int get_value(const std::string& property) const {
    auto it = values.find(name);

    if (it != values.end()) {
      return it->second;
    }

    return -1;
  }

  std::map<std::string, int> values;
};

And on the Lua side:在 Lua 方面:

-- Lua
p = player.new()
print(p.score)

So when I call p.score in Lua, it gets translated to the call to the player::get_value function on C++ side with the value of property "score" ?因此,当我在 Lua 中调用p.score时,它会被转换为对 C++ 端的player::get_value函数的调用,其值为property “score”?

SOLUTION解决方案

Thanks to @Vlad for the directions!感谢@Vlad 的指导!

I came up using sol2 which is in my opinion a very nice C++ library binding to Lua!想到了使用sol2 ,在我看来,这是一个非常好的 C++ 库绑定到 Lua!

Here is how it can be done with sol2:这是使用 sol2 完成的方法:

struct Player {
  sol::object get(const std::string& key, sol::this_state state) {
    const auto& it = values.find(key);

    if (it != values.cend()) {
      return sol::make_object(state, it->second);
    }

    return sol::lua_nil;
  }

  std::map<std::string, int> values;
};

int main() {
  Player player;

  player.values.emplace("score", 123);

  sol::state lua;

  lua.open_libraries(sol::lib::base);
  lua.new_usertype<Player>("Player", sol::meta_function::index, &Player::get);
  lua.set("player", &player);

  lua.script(R"(
    print("Player score: ", player.score)
  )");
  return 0;
}

Console output控制台输出

Player score:   123

The object player should have metatable set with fields __index / __newindex set to C function that will be called when Lua is trying to read or write the field that doesn't exist in the Lua object.对象player应该将元表设置为字段__index / __newindex设置为 C 函数,当 Lua 尝试读取或写入 Lua 对象中不存在的字段时,将调用该函数。

Normally the Lua object representing the native object ( player in your case) will be a userdata , either storing the pointer to the C++ object, or hosting it within its storage.通常,代表本机对象(在您的情况下为player )的 Lua 对象将是一个userdata ,要么存储指向 C++ 对象的指针,要么将其托管在其存储中。

The metamethods __index / __newindex will receive in arguments the reference to the object being queried, the key value (eg your score field), and the value to store in case of __newindex metamethod.元方法__index / __newindex将在参数中接收对被查询对象的引用、键值(例如您的score字段)以及在__newindex元方法的情况下要存储的值。 So you can find your native object and desired property easily.因此,您可以轻松找到您的本机对象和所需的属性。

Some people prefer using existing binding solutions - tolua++/sol/luabind/etc, but it's very simple to implement required functionality yourself.有些人更喜欢使用现有的绑定解决方案——tolua++/sol/luabind/etc,但自己实现所需的功能非常简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM