【问题标题】:How to expose C++ unions to Lua如何将 C++ 联合暴露给 Lua
【发布时间】:2015-10-26 02:40:00
【问题描述】:

对于我正在处理的项目,我需要将另一个库中的一些 C++ 类公开给 Lua。不幸的是,这个库中最重要的类之一有很多联合和枚举(the sf::Event class from SFML),从quick Google search 我发现没有将 C++ 联合暴露给 Lua。我不介意它是通过 Lua/C API、库还是绑定生成器公开的,只要它可以工作。但是,我不想使用绑定生成器,因为我希望能够在 C++ 中创建一个对象,然后将该对象的实例公开给 Lua(除非使用绑定生成器可以)

【问题讨论】:

  • 用一些 setter 和 getter 公开那个类怎么样?
  • @Calvin 在我的情况下(暴露 sf::Event),这是一个非常混乱的解决方案,因为它涉及大量带有大量 if 语句的 getter。我也遇到了 sf::Event 的吸气剂和我正在使用的库的问题。但我会考虑使用另一个库/使用 Lua/C API 来尝试它。
  • 你已经被困了一段时间了。你学过 C API 吗?你很了解 Lua 元表吗?如果您了解用户数据和元表的工作原理,这相对简单。这是related post
  • @Mud 我了解 Lua C API 和 Lua 元表,我只是不确定 C++ 联合是否会产生任何问题(我从未在自己的类中使用联合,我是模板库以前使用 getter 访问 union 时无法正常工作,并且该问题在开放的 4 天内得到了一条评论,表明该问题有一些困难,或者 SO 过于饱和,需要赏金才能得到答案>:( )
  • @Orfby 您之前的问题(大约一个月前)是关于 LuaBridge 和/或绑定库的。绑定库可能不支持联合,但对于 C API 来说不是问题。您的 C++ 对象作为用户数据公开。该用户数据通过 __index 元方法公开诸如“大小”和“文本”之类的字段。他们在工会中是完全无关的。这些字段返回像 SizeEvent 这样的对象,它只是更多的用户数据,每个都有自己的元表。如果你不知道这意味着什么,你会想比现在更好地学习 C API 和/或元表。

标签: c++ lua unions


【解决方案1】:

要注册 C/C++ 函数,您首先需要使您的函数看起来像 Lua 提供的标准 C 函数模式:

extern "C" int MyFunc(lua_State* L)
{
    int a = lua_tointeger(L, 1); // First argument
    int b = lua_tointeger(L, 2); // Second argument
    int result = a + b;

    lua_pushinteger(L, result);

    return 1; // Count of returned values
}

每个需要在 Lua 中注册的函数都应该遵循这个模式。 int 的返回类型,lua_State* L 的单参数。和返回值的计数。 然后,您需要在 Lua 的注册表中注册它,以便将其公开给脚本的上下文:

lua_register(L, "MyFunc", MyFunc);

为了注册简单的变量,你可以这样写:

lua_pushinteger(L, 10);
lua_setglobal(L, "MyVar");

之后,您可以从 Lua 脚本调用您的函数。请记住,在运行具有您用来注册它们的特定 Lua 状态的任何脚本之前,您应该注册所有对象。

在 Lua 中:

print(MyFunc(10, MyVar))

结果:

20

我想这对你有帮助!

【讨论】:

    【解决方案2】:

    如果您愿意使用 boost::variant 而不是联合,您可以尝试使用我的 LuaCast 库。

    我也会尝试添加联合作为基本类型。

    【讨论】:

    • OP 将来自不同库的代码暴露给 Lua:他们不太可能有能力修改第 3 方库。
    • @Yakk 这就是他们需要生成包装器的原因
    猜你喜欢
    • 2010-12-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多