使用 SWIG 包装 c++ 类以在 Lua 中使用它 - 需要简单的示例

Posted

技术标签:

【中文标题】使用 SWIG 包装 c++ 类以在 Lua 中使用它 - 需要简单的示例【英文标题】:Wrapping c++ class to use it in Lua using SWIG - need simple example 【发布时间】:2012-01-28 00:00:42 【问题描述】:

在使用 SWIG 和 lua 方面,我是一个绝对的初学者,也是一个平庸的 C++ 开发人员,我似乎不明白如何将 C++ 类与 Lua 绑定。

我的最终目标是拥有一个类的实例,将其传递给我的 lua 脚本,该脚本以某种方式操作该对象,然后我在 C++ 中检索该对象并做任何我想做的事情。

所以...我已经下载了 Lua 和 C++,编译了一些示例,我可以在我的 c++ 程序中运行一些 lua 脚本。到目前为止一切顺利。

现在,我已经下载了 SWIG。我在 Windows 7 上使用 VC2010。据我了解,我想创建一个接口文件。所以我创建了一个,example.i:

%module creature
class Creature

public:
    Creature(void);
    Creature(int id);
    ~Creature(void);

(...) the rest of my class here

(刚刚将 %module 生物添加到我的 Creature.h 并将其保存为 bio.i)。我使用 SWIG 运行

 swig -c++ -lua creature.i

得到了我的 monster.cxx 文件。

现在,我现在可能会让自己难堪,但是……我不知道下一步该做什么。我想以某种方式构建输出文件吗?我现在如何使用它?我在这里读到http://www.swig.org/Doc1.3/Lua.html 我需要将生成的文件 (*.cxx) 与我的其余代码链接(所以我只需将文件包含在我的项目中并添加行 #include "Creature.h ”)。但是当我编译时,我会得到类似的错误

error C2065: 'LUA_GLOBALSINDEX' : undeclared identifier
error C2036: 'const luaL_reg *' : unknown size

我也尝试过使用 MinGW 编译它,但我遇到了同样的问题。如果有人可以向我展示如何一起使用这些工具的示例或分步教程,那就太好了,因为我很难掌握整个想法。这绝对是由于我对如何使用它的基础知识缺乏了解,所以请对菜鸟温柔。

任何帮助将不胜感激。

【问题讨论】:

在 Lua 发行版中搜索丢失的标识符告诉我它已在 5.2 版中被删除 - 可能 SWIG 尚未更新以使用它。尝试将 Lua 降级到 5.1。 考虑到 Lua 5.2 的接受度,许多人会考虑将其用作 up 级,而不是降级。 它可以编译,但现在我得到一个链接器错误:错误 LNK2019:未解析的外部符号 _lua_error 在函数 __wrap_new_Creature 中引用。但是即使我设法编译了它,我以后如何使用它呢? @NicolBolas 我一直没有关注 Lua 开发新闻。 Lua 5.2 不受欢迎吗?我可以在哪里阅读更多相关信息? 只是想让你们知道,这确实是 5.2 的问题,降级到 5.1 后我编译没有任何问题。我仍然需要学习如何使用这些工具,但我可能会以某种方式管理。 【参考方案1】:

SWIG 是将脚本语言链接到 C 或 C++ 代码的工具。它作为 预处理 步骤工作:您在 .swig 文件上运行 SWIG 可执行文件,该文件会生成一些 C 或 C++ 代码。然后,您将该代码构建到您想要链接到该脚本语言的任何项目中。

SWIG 的 Lua 支持肯定与 Lua 5.2 不兼容。事实上,你会发现很少有与 Lua 5.2 兼容的代码。如果你真的想用 Lua 代码做点什么,至少暂时坚持使用 5.1。

【讨论】:

因此,如果我设法编译包含在我的对象中的那个 c++ 文件,我将它(使用#include)包含在我使用 lua 并调用 luaopen_creature 的类中就足够了吗(L);?还是有不同的方式来构建这些包装器?抱歉,我是新手。 通常,SWIG 用于创建 Lua DLL,这些 DLL 使用 require Lua 函数打开。如果您尝试使用静态 SWIG 模块,则必须使用 STATIC_LINKED #define 构建 SWIG 源文件。要将其初始化为 Lua 状态,您需要运行 luaopen_* 函数,其中 * 是 SWIG 模块的名称。 SWIG 的文档解释了其中的大部分内容,所以去看看吧。 最近刚刚在 SWIG 开发源中添加了一个添加 Lua 5.2 支持的补丁(非常简单,只需进行一些调整),因此在下一个版本中应该可以。 我会接受你的回答 Nicol,尽管你没有真正解释任何我不知道的事情,除了 5.2 的问题,我很感激。【参考方案2】:

我的最终目标是拥有一个类的实例,将其传递给我的 lua 以某种方式操作该对象的脚本,然后我检索 C++ 中的那个对象,然后做我想做的任何其他事情。

我可能弄错了,但您并没有将 C++ 类的实例“传递”给 Lua,您真正要做的是创建与 Lua 的 C++ 绑定,从而您实际上是在 Lua 脚本本身中实例化 C++ 类。

即假设您有一个名为 Foo 的 C++ 类,其中包含一个名为 add(x, y) 的方法。然后,您可以通过执行以下操作在 Lua 中实例化并使用该类(假设您已使用 Swig 创建包装文件)。

foo_instance = Foo()
foo_instance:add(4, 3)

在我的 C++ 程序中使用 Swig 和 Lua 时遇到了一些不幸,所以我写了一个教程(这样我就不会忘记我是如何做到的)。你可以在这里查看...http://glennmccord.wordpress.com/2012/11/05/binding-c-to-lua-using-swig/

希望它可以帮助您入门。

【讨论】:

以上是关于使用 SWIG 包装 c++ 类以在 Lua 中使用它 - 需要简单的示例的主要内容,如果未能解决你的问题,请参考以下文章

将自定义代码添加到 SWIG 包装器

Swig 包装 GLM 库

SWIG:你能否使用 SWIG 专门使用 C++ 头文件使 C++ 在 Python 中可用?

SWIG:Lua - 将 c++ 实例作为 lua 函数参数传递

如何使用 SWIG 从 lua 中的 C++ 类继承

SWIG_exception() 将 SWIG_RuntimeError 打印为字符串