Lua脚本实现
我目前正在致力于将 Lua 实现到我正在开发的应用程序之一中。 目前我只是使用 C api 并使用 lua_register 注册函数,但我希望能够将静态和非静态函数指针传递给某些类方法。
我在网上找到了某些库,但由于我只需要很少的它们提供的整体功能,我想知道是否有一种简单的方法可以做到这一点。
谢谢。
I'm currently working on implementing Lua into one of the applications that I'm working on. Currently I'm just using the C api and registering functions using lua_register, but I'd like to be able to pass static and non static function pointers to certain class methods.
I've found certain libraries on the net, but since I need very little of the overall functionality they provide I was wondering if there's an easy way to do this.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
复杂的库 API 通常可以使用 SWIG 快速且(几乎)完全地包装。 在这种情况下使用 SWIG 的一个优点是,可以轻松构建基于 SWIG 的包装器,从而可以在 18 种主要语言,包括 Lua、Perl、Python、Ruby 和 Java 等。
如果 Lua 是您首选(也可能是唯一)关注的问题,那么我建议您学习使用
luaL_register()
是用 C 语言构建 Lua 模块的策略的核心。以这种方式构建模块的优点是可以将所有函数保存在一个名称空间中没有任何开销。 您需要制作一个与 Lua C 函数调用约定相匹配的包装函数(就像使用 lua_register() 一样),并从堆栈中收集 Lua 参数、调用包装函数并推送任何返回值和输出参数返回Lua堆栈。 有关如何进行此操作的详细概述可以在《Lua 编程》一书中找到。 第一版的在线副本在第 26 章中讨论了库的创建,但是是为卢阿5.0。 我强烈建议任何认真使用 Lua 的人都拥有一份最新版本的 PiL。不幸的是,Lua 5.1 与 5.0 最大的不同之处在于使用
require
动态加载模块(C 和 Lua)。这是一个在 Lua 5.1 中工作的 C 库的完整(如果很小)示例。 我们从在 C 文件中实现包装器开始:
特别注意,唯一需要导出的函数是 luaopen_sm(),其名称必须与将使用的模块的名称相对应与
require
以及 DLL 文件的名称。 将该文件编译为名为sm.dll
的 DLL(在类 Unix 系统上可能名为libsm.so
),然后可以在 Lua 脚本中加载和使用它,例如this:此示例虽然未经测试,但应该可以编译并运行。 有关包装
math.h
中大多数函数的完整示例,请参阅 与 Lua 一起分发的math
模块的源代码。 由于这些薄包装器包含大量重复代码,因此 SWIG 等工具通常只需给出每个函数的声明即可创建它们。C++ 类的包装方法原则上类似。 每个 Lua 可调用的包装函数都需要一个可以在 C++ 端映射到
this
的参数,并且它必须实现为模块静态函数或静态成员函数,该函数也可以定位目标对象实例以及转换其他参数。 SWIG 特别擅长构建这种包装器,并在此过程中隐藏了许多血淋淋的细节。A complex library API can often be wrapped quickly and (nearly) completely using SWIG. An advantage of using SWIG in this case is that it is easy to build SWIG-based wrappers that enable use of the library in 18 major languages including Lua, Perl, Python, Ruby, and Java, among others.
If Lua is your preferred (and possibly only) concern, then I'd recommend learning to use
luaL_register()
at the core of a strategy to build Lua modules in C. An advantage of building a module this way is that you keep all of your functions in a single name space without any overhead. You will need to craft a wrapper function that matches the Lua C function calling convention (just as you do withlua_register()
) and that gathers the Lua arguments from the stack, calls the wrapped function, and pushes any return value and out parameters back to the Lua stack. A good overview of how to go about this can be found in the book Programming in Lua. The online copy of the first edition discusses library creation in Chapter 26, but was written for Lua 5.0. I strongly urge anyone seriously using Lua to own a copy of the current edition of PiL.Unfortunately, one area where Lua 5.1 differs the most from 5.0 is in the dynamic loading of modules (both C and Lua) with
require
.Here's a complete (if small) example for a C library that works in Lua 5.1. We start with the implementation of the wrapper in a C file:
Note in particular that the only function that need be exported is
luaopen_sm()
, whose name must correspond to the name of the module that will be used withrequire
, and with the name of the DLL file. With that file compiled as a DLL namedsm.dll
(probably namedlibsm.so
on Unix-like systems), then it can be loaded and used in a Lua script like this:This example, although untested, should compile and run. For a complete example wrapping most functions from
math.h
, see the source to themath
module that is distributed with Lua. Because these thin wrappers contain a lot of repetitive code, tools like SWIG are often able to create them given only the declaration of each function.Wrapping methods of a C++ class is similar in principle. Each Lua-callable wrapper function is going to need an argument that can be mapped into
this
on the C++ side, and it must be implemented as either a module-static function or static member function that also locates the target object instance as well as converts the other arguments. SWIG is particularly good at constructing this kind of wrapper and hides a lot of gory details along the way.