Lua 可以嵌入和扩展[1]其他语言编写的代码或应用程序。其他语言中的代码和值可以暴露给 Lua,反之亦然。以下列出了 Lua 与其他语言之间绑定的低级和高级解决方案。
Lua C API
与 Lua 绑定的最直接方法是使用 Lua C API。C API 由两部分组成:基本 API (lua.h) 提供了 C 和 Lua 之间所有交互的原始函数,而辅助库 (lauxlib.h) 提供了用于某些常见任务的更高级别的函数。[2]
启用 API 检查
默认情况下,Lua C API 几乎不进行对传递给它的参数的健全性检查。例如,传递不正确的堆栈索引会导致段错误或随机数据损坏。您应该始终在任何调试版本中启用 API 检查。您可以通过使用选项-DLUA_USE_APICHECK
编译来实现。luaconf.h
使用此 C 宏来定义luai_apicheck
以在各种地方调用assert()
(您也可以编辑此定义以执行可能更有用的操作)。
示例
可以通过检查 Lua 自身标准库的源代码 (src/*lib.c
} 来找到使用 C API 的一些示例。例如,数学库 (math.*
) 在文件src/lmathlib.c
中实现。此文件的基本形式如下所示。首先,我们导入各种头文件,包括 C API (lua.h) 和辅助库 (lauxlib.h)
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
然后定义了在 C 中实现的各种 Lua 函数。它们都具有相同的签名,并且参数通过 Lua 自身的堆栈传递。例如,sin 函数定义如下。luaL_check_number()
用于检查sin
函数参数的正确类型。lua_pushnumber()
用于返回计算出的正弦值。请注意,math_sin()
函数的返回值是返回的值的数量(lua 函数可以返回多个值)。
static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
return 1;
}
这些函数通过构建一个函数指针和名称表,然后调用luaL_register()
来注册到 Lua 中。常量pi
和huge
是单独设置的。此注册代码放置在一个名为luaopen_math()
的函数中,该函数可以静态调用(例如,从 linit.c)或动态调用(通过 Lua 的共享库加载机制通过require
)。
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"cos", math_cos},
{"sin", math_sin},
... etc...rest of table not included, but make sure you finish of with:
{NULL, NULL}
};
/*
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
return 1;
}
将 C/C++ 与 Lua 绑定
C
- [LuaAutoC] (5.2) - 在运行时自动包装 C 函数和结构体。
- [LuaNativeObjects] (5.1) - 一个用 Lua 编写的 C 绑定生成器。它将 C 结构体转换为对象。
- [luapi] (5.0) - 一个基于官方 Lua API 的 C API。
- [CaLua] (5.0) - 一种将 C 函数和结构体绑定到 Lua 的方法,并在 Lua 中使用 C 指针、数组和函数。(使用 x86 汇编)
C 外部函数接口 (FFI)
- [Alien] (5.1) - Lua 的外部函数接口 (FFI)。[FFI] 允许 Lua 代码直接调用 C 函数,而无需编写 C "胶水" 代码,因此您可以使用 Alien 纯粹用 Lua 编写 C 扩展。(包装 libffi)
- [C/Invoke for Lua] (5.1) - 从 Lua 使用 [C/Invoke] 直接调用 C 库(DLL、.so 文件),类似于 Microsoft 的 P/Invoke 和 Python 的 ctypes。(类似于 Alien)
- [LuaJIT FFI] 允许从 Lua 代码调用外部 C 函数并使用 C 数据结构。它解析纯 C 声明并支持 C99 以及一些 GCC/MSVC/C++ 扩展。
- [luaffi] (5.1) - LuaJIT FFI 的 Lua 实现。
- [cffi-lua] (5.1, LuaJIT, 5.2, 5.3, 5.4) - 主要与 LuaJIT FFI 兼容(但与新 Lua 版本集成),但可移植(基于 libffi)并且从头开始实现。
C 内联
- [lua-tcc] (5.1) - 对 TCC 的简单接口,TCC 是 Fabrice Bellard 开发的一个快速运行时 C 编译器,它允许 Lua 脚本编译 C 代码并在运行时将其注册为 Lua 可调用的 C 函数。有意限制以避免 TCC 在多环境中的错误,这在 Lua 中会过于诱人。
- [Luatcc] (5.1) - 另一个更完整的 Lua 绑定,用于 libtcc,它是 [Tiny C Compiler] 的核心库。它允许直接从 Lua 编译和加载 C 代码,包括直接从 C 源代码加载 C 模块的功能。
- InlineCee 提供类似的方法,在进程外调用其他编译器。
C++
已经开发了各种 C++ 或 C++ 模板绑定来简化 C++ 中的过程
- [Luaaa] (5.1, 5.2, 5.3, 5.4) - 一个用于将 C++ 类和函数导出到 Lua 的单头文件库。无依赖,轻量级。支持导出 lambda 表达式,双向回调,将 STL 容器映射到 Lua 表,从导出类继承,自定义内存分配;易于使用的接口;将原生对象导出为 userdata 而不是 table 以获得更好的性能;可以选择禁用 STL/RTTI 以用于嵌入式开发。
- [MiniLua (5.3, 5.4)] - 用于加载 Lua 文件并将值获取到 C++ 应用程序的最小 Lua 接口。
- [Lua-Adapter] (5.3, 5.4) - 使用这个轻量级包装器/适配器类作为 Lua 和 C++ 之间的简单“接口”。
- [CppLua] (5.0 & 5.1) - Lua API 的 C++ 包装器;处理类成员函数。
- [LuaCppInterface] (5.2) - Lua API 的 C++ 包装器。使用 TMP 使调用/传递函数、处理协程和填充表格变得容易且类型安全。
- [sol2] (5.1, LuaJIT, 5.2 & 5.3) - 一个快速、强大且易于使用的 C++14 包装器,用于 API,包括对表格索引、用户定义类型、元方法、协程等的支持。
- [sol] (5.2) - 一个 C++11 易于使用且类型安全的 Lua API 包装器。
- [Diluculum] (5.1) - 一个旨在使 C++ 和 Lua 的共存更加和谐的库。
- [Tomaka17's lua wrapper] (5.2) - 使用 C++11 的简单 Lua 绑定,支持类和函数注册、自定义成员函数、多个返回值、表格等。
- [Luabind] (5.1 & [5.2]) - 基于模板的 C++ 类和函数绑定,使用 Boost 库。该库似乎被 [原始作者] 放弃了,但一些或多或少积极维护的 [分支] 存在,例如 [3] 或 [4]。
- [LuaBridge] (5.1 & 5.2) - 轻量级、无依赖、基于模板的库,用于将 C++ 类/函数导出到 Lua 环境。
- [LuaBridge3] (5.1 & 5.2 & 5.3 & 5.4 & LuaJIT & Luau, with or without exceptions) - 轻量级、无依赖、基于模板的库,用于将 C++ 类/函数导出到 Lua 环境,LuaBridge 的继任者 ?,具有更多功能和修复。
- [SLB] (5.2) - 简单 Lua 绑定器,一个跨平台、小巧、易于集成、基于模板的库。与 Luabind 或 boost-python 非常相似,但 SLB 不需要 boost 或任何其他依赖项。
- [Luna] (4.0), LunaWrapper (5.1) 和 LunaFive (5.2) - 一种干净的基于模板的方法,用于将 C++ 类绑定到 Lua。另请参见 [LTN5] 和 SimplerCppBinding。
- LunaWrap (5.2 & 5.3) - 一种干净的基于模板的方法,用于将任意类型推送到 Lua 并从 Lua 获取它们,以及一个用于 C++ 成员函数的编译时“代理”函数(“int foo(lua_State*)”)生成器!
- [MLuaBind] (5.1) - 基于模板的 C++ 类和函数绑定,使用 Loki 库。
- [MultiScript] (5.1) - 一个简单的库,演示了 Lua 独立的 C++ 接口,用于绑定 C++ 类和函数。
- [OOLua] (5.1, 5.2 & 5.3) - 跨平台模板生成器绑定,没有依赖关系。
- [Selene] (5.1, 5.2, 5.3) - 死简单且直观的 C++11 绑定,支持类注册和函数。
- [Sweet Lua] (5.1) - 基于模板的 C++ 类和函数绑定。(MSVC)
- [lux] - 通过 C++ 模板和参数重载在编译时发出函数
- [nlua] - C/C++ 函数的“命名空间 lua”绑定,类似于表的用法,基于模板(没有 boost)
- [LuaWrapper] - 一个单头库,提供类型安全且直观的函数,例如 luaW_to<T> 和 luaW_push<T>,用于任意类型,以简化使用 Lua 管理 C++ 类。
- [Lutok] - 用于 Lua 的轻量级 C++ API。Lutok 提供了围绕 Lua C API 的薄 C++ 包装器,以简化 C++ 和 Lua 之间的交互。这些包装器大量使用 RAII 来防止资源泄漏,公开 C++ 友好的数据类型,通过异常报告错误,并确保在遇到错误时 Lua 堆栈始终保持不变。该库还提供了一小部分基于包装器的杂项实用程序函数。
- [integral] (5.1, LuaJIT, 5.2, 5.3, 5.4) - 没有依赖关系的 C++ 库,用于创建 Lua 绑定。
- [lua-intf] (5.1, 5.2 & 5.3) - 用于 Lua 的纯 C++11 API 和绑定(仅限头文件),支持 lua 堆栈 API,一个更高层次的 API,可以像 C++ 类对象一样引用 lua 对象,还可以导出 C++ 类和函数以供 lua 脚本使用。导出绑定支持自定义 C++ 类型、多个返回值、C++ 共享指针、输入/输出参数,还可以使参数可选或具有默认值。新版本还附带可选的 Qt 数据类型映射(QString、QVariant、QByteArray 等)。
- [LuaState] (5.1 & 5.2) - C++11 模板库(clang、gcc 和 VS 12)没有 boost。旨在易于使用且尽可能快。从 Lua 到 C++ 的基于 lambdas 的绑定。
- [Kaguya] (5.1 , 5.2 , 5.3) - 带有 boost 的 C++03 或 C++11 模板库。
- [Lua-Primer] (5.2, 5.3, Eris) - C++11 模板库。不仅创建了与 lua 的绑定,而且以一种支持使用 Lua Eris 进行轻松、无缝序列化的方式进行。另请参见 [github] 中对 eris 的描述。
- [Ponder] (5.3) Ponder 是一个 C++ 反射 API,可以将声明的 API 暴露给 Lua。易于使用。
- [自动绑定] 使用 C++11 模板推断 C 函数参数,自动创建包装器,将本机 C 函数暴露给 lua 代码。
另请参阅
从 C/C++ 调用 Lua
这些框架和文章是单向绑定:从 C/C++ 调用 Lua 函数,传递参数并获取返回值。
在 C++ 中嵌入 Lua
这些框架比之前的框架更广泛:它们允许你的 C++ 程序与 Lua 解释器完全交互,但将扩展 Lua 的任务留给其他绑定系统(SWIG、tolua++ 等)。
- [lua_icxx]:(发音为“lua-ix”)用于 C++ 的 Lua 解释器;调用 Lua 函数和用户数据(类)方法,使用表,创建函数沙箱,使用多个返回值,评估表达式和脚本等等。它是使用 SWIG 和 tolua++ 等绑定的缺失环节。
自动绑定生成器
- [toLua] (5.2) - 如果有大量信息需要绑定,那么使用绑定生成器来自动化该过程会有所帮助。toLua 就是这样一个工具。准备一个包文件,它是 C/C++ 接口的清理版本。这种技术的另一个优点是,如果 Lua C API 发生重大变化,Lua 版本之间可能需要更少的修改工作。
- [tolua++] (5.1) - tolua 的扩展版本,具有一些面向 c++ 的额外功能。另请参阅 CompilingToluappWithoutScons(在没有 SCons 的情况下编译 tolua++)。
- [CPB] (5.0) - 用于 Lua 脚本语言的简单、快速且功能强大的绑定库。它从编译器的符号中获取信息,并直接从中生成绑定代码。(MSVC)
- [SWIG] (5.0/5.1) - 简化的包装器和接口生成器,它可以在你的 C/C++ 代码和各种脚本语言(Python、Perl、Tcl/Tk、Ruby 等)之间生成绑定,包括 Lua。一个很大的优势可能是 *一个* 接口文件(类似于 tolua/tolua++ 中使用的文件)用于绑定到 SWIG 支持的所有语言。另请参阅与 Lua 相关的 SWIG 文档 [5]。
- [luna-gen] - lua 绑定代码生成器,支持属性、继承(从 lua 和 c++)、命名空间、枚举、类型检查、c++ 异常处理、采用策略、g++ 和 MSVS、运算符重载、用户可配置的自定义字符串和数字/枚举类型等等。编译和执行速度快(比 luabind 和 SWIG 快得多),人类可读的输出代码,没有 boost 依赖。
- [dub] - 使用 Doxygen 解析 C++ 头文件。支持属性、继承、类型转换、Lua 包装、枚举、异常处理、运算符、自定义类型绑定、C++ 模板解析、带有错误处理的 C++ 回调、带有运行时类型解析的重载方法等等。生成的代码经过优化,尽可能快(返回值优化、内联对象等等)。
- [Ponder] - 在使用 Ponder 声明 API 后,可以自动将其公开到 Lua。Ponder 是一个 C++ 反射系统,也支持 Lua 绑定,以及 XML/JSON 序列化。
DLL 的代理包装器
动态链接库可以导出函数信息。 [FuBi] 描述了一种从脚本(或 RPC)调用这些函数的方法。 Lua 可以使用此功能 [6]。
其他
- [wxScript] (5.0) - 一组抽象类,用于为您的 wxWidgets 应用程序/库添加脚本解释器支持。
其他语言
Ada
Bash Shell
luabash 工具是 bash shell 的一个动态加载模块,它在 bash shell 和 lua 脚本语言之间架起了一座桥梁。 这使得复杂的嵌入式代码段可以被高效的 lua 代码替换,并且可以提高 shell 脚本的速度,而无需大幅重写现有代码。
基础
- [FreeBASIC] - 一个开源 BASIC 编译器,它附带 Lua 头文件和库。
- [PBLua] (5.0.2) - 一个包装 Lua 5.0.2 的 Purebasic 库。(已弃用)
- [PowerBLua] (5.0) - 用于包装 Lua 的 PowerBASIC 包含文件和源代码(正在进行中)。
- [BlitzMax] (5.1.2) - 一个 BlitzMax 模块,包装 Lua 5.1.2(注意:该链接目前指向此维基(这通常在这个列表中是一个坏主意),但一旦该包拥有自己的网站,它就会改变)
COBOL
D
- [LuaD] (5.1) - D 编程语言的 Lua 绑定和高级接口。
- [DLua] (5.1) - D 编程语言的 Lua 绑定。
Erlang
- [erlua] (5.1) - 旨在实现 Erlang 和 Lua 之间的无缝互操作性。
- [erl-lua] (5.1) - 一个 Erlang 链接驱动程序,允许将 Lua 嵌入到 Erlang VM 中。
- [erluna] (5.1) - Erlang 的 Lua 绑定。
Fortran
- [Aotus] (5.3) - 旨在实现无缝使用 Lua 脚本配置 Fortran 应用程序,使用 ISO-C-Binding。
- [f2k3-lua] - 通过 Fortran 2003 ISO-C-Binding 与 Lua 交互。
Go
- [golua] (5.1) - Go 的 Lua 绑定。
- [luar] (5.1) - 在 golua API 之上的反射层,提供了一种简化的方法将 go 函数发布到 Lua VM。
- [go-lua-test](5.1) - 使用各种 Go 的 Lua 绑定的示例
Haskell
- [HsLua] (5.1) - Haskell 的脚本语言 Lua 绑定。
Java
- [LuaJava] (5.1) - 允许用 Lua 编写的脚本操作用 Java 开发的组件(JNI 到原生 Lua)反之亦然。
- [JNLua] (5.2, 5.1) - 另一个 Java JNI <-> Lua 桥接。包括 JSR 223(Java 平台的脚本)提供程序。
- [jna-lua] - Java JNA <-> 原生 Lua 桥接。
- [java-lua] - Java JNI Lua 桥接。从 Java 调用 Lua 以及从 Lua 调用 Java 回调
LabVIEW
Objective-C
- [LuaObjCBridge] (5.1) - 从 Objective-C 调用 Lua 反之亦然(MacOS X Cocoa)。
- [LuaCore] (5.1) - 一个基于 LuaObjCBridge 的框架,可以轻松设置和运行 Lua 脚本。
- [LuaCocoa] (5.1) - LuaObjCBridge/LuaCore? 的精神继承者,Lua 和 Obj-C 之间的桥梁,并使用 Apple 的 BridgeSupport? 来填补剩余的非 ObjC 区域(例如结构体、C 函数、内联函数)以访问平台上的所有 API。还包括一个命令行工具,适合通过 ScriptingBridge? 在 Lua 中编写 AppleScript?。(Mac OS X)。
- [iPhone Wax] (5.1) - Lua 和所有 Objective-C/Cocoa
Touch 类之间的桥梁。
- [Objective Lua] (5.1) - 将类似 Objective-C 的语法引入 Lua。
- [TLC] (LuaJIT 2) - 一个轻量级(不到 400 行,纯 Lua)桥接,将 Objective-C 对象和方法暴露给 Lua。
OCaml
- [ocaml-lua] (5.1.x) - 从 OCaml 调用 Lua,反之亦然(仅在 Linux 上测试,应该适用于 OS X)。
Pascal
Perl
PHP
Python
- LunaticPython [7] (5.1) - Lua/Python 双向桥接。允许在 Python 程序中嵌入 Lua 解释器,以及在 Lua 程序中嵌入 Python 解释器。
- [Lupa] (LuaJIT2)(5.1, 5.2, ?5.3) - 在 Python 中嵌入 Lua。允许 Python 和 Lua 代码之间的双向通信,并尝试在两侧保持一致的行为。
- ffilupa [8] (5.2, 5.3) - Python 和 Lua 之间的现代双向桥接。使用 CFFI 作为后端将 Lua 集成到 Python 中,在 CPython 和 PyPy? 上运行速度都很快。灵感来自 Lupa。
R
- RClient [9] (LuaJIT) - 用于 Rserve 的 LuaJIT 客户端,用于托管一个(本地或远程)R 会话,并建立连接。一个允许在 LuaJIT 中执行任意 R 程序的库。
- Lupa(上面提到的 python 包)+ reticulate(R 中从 CRAN 安装的包:https://rstudio.github.io/reticulate/) - 允许在 R 会话中通过 python 会话作为中间媒介访问 Lua 语言和对象,该媒介由 Reticulate 设置。最好查看 LunaticPython 和 Lupa 中的示例,以了解如何设置和使用此解决方法。
Ruby
Tcl
Terra
[Terra] 是一种新的低级系统编程语言,旨在与 Lua 编程语言无缝互操作。
与 C 一样,Terra 是一种简单、静态类型、编译语言,具有手动内存管理。但与 C 不同的是,它从一开始就被设计为与 Lua 互操作。Terra 函数是使用 terra 关键字创建的一流 Lua 值。在需要时,它们会被 JIT 编译成机器代码。
您可以将 Terra 和 Lua 用作
具有高性能扩展的脚本语言。虽然 Lua 和其他动态语言的性能一直在提高,但低级抽象让您在需要时能够对性能进行可预测的控制。
软件 DSL 的 JIT 编译器。使用 Lua 元编程 Terra。允许您将用 Lua 编写的领域特定语言 (DSL) 编译成高性能 Terra 代码。将 Terra-Lua 程序嵌入其他软件作为库,允许您在现有软件中添加 JIT 编译器。
独立的低级语言。Terra 的设计使其能够独立于 Lua 运行。事实上,如果您的最终程序不需要 Lua,您可以将 Terra 代码保存到 .o 文件或可执行文件中。在这种情况下,Lua 充当强大的元编程语言。您可以将其视为 C++ 模板元编程的替代品,具有更好的语法和更友好的特性。
框架
CORBA
Windows COM
- LuaCom - (5.1/5.0) Lua 与 Microsoft 组件对象模型 (COM) 的接口。从 Lua 调用 COM 对象并在 Lua 中实现 COM 对象。
Windows .NET
Firefox
- [Moonshine] - Firefox 网络浏览器的嵌入式 Lua 环境。允许 Firefox 扩展使用 Lua 而不是 Java
Script 开发。实现为一个扩展 (XPI),用 XUL、Java
Script 和 C++ 编写。
XML-RPC / SOAP
另请参见
最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于2023年6月14日下午9:00 GMT (差异)