二进制模块教程 |
|
版本说明:此页面适用于早期版本的 Lua(4.0 和 5.0beta),使用 loadmodule
扩展。Lua 5.1 使用 package.loadlib
和 require
。Lua 5.0 使用 loadlib
。)
此页面的目标是展示如何轻松地从现有的 Lua 扩展创建 Lua 二进制模块,而无需更改扩展的原始源代码 - MartinSpernau
目标:将现有的 Lua 扩展(最初是静态链接到 Lua 可执行文件)编译为动态链接库,以便在运行时通过 Lua 二进制模块 中描述的 loadmodule() 功能加载。
特殊目标:不要更改原始代码(这很可能是由其他人编写的)
讨论:Lua 扩展通常包含许多源文件和头文件,这些文件实现所需的功能。这些函数通过特殊的包装函数以及一个“open”函数来访问 Lua 解释器,该函数将这些函数“注册”到当前的 Lua 状态。(关于这方面的讨论可以在 Lua 参考手册和 将代码绑定到 Lua 中找到)
loadmodule 功能 (Lua 二进制模块) 利用了这样一个事实:每个扩展基本上都定义了一个“open”函数。由于这些函数可以具有特定于每个扩展的不同名称(例如 lua_bitlibopen、lua_fooinizialize 等),loadmodule 模块将库打开代码包装到一个定义的函数 luaLM_import 中。它还定义了 luaLM_version,这对于检查扩展与核心 Lua 库的版本兼容性是必需的。
这两个函数现在充当要编译的动态链接库的唯一外部入口点。当从 Lua 中调用 loadmodule('modname') 时,它将尝试为该扩展加载一个 dll(在 Windows 上,这将是 luamodname.dll)。然后,它将通过调用 luaLM_version 检查版本,如果一切正常,则调用 luaLM_import,这将依次初始化函数的实际注册。
将现有扩展移植为支持 loadmodule 的 dll 通常,只需将两个必要的 luaLM 函数添加到扩展中,并将其编译为动态链接库即可。这通常通过编写一个简单的 .def 文件来完成,该文件声明这两个函数。
待办事项:添加有关如何使用常见编译器执行此操作的说明
作者想描述一种略有不同的方法,其优点是不需要对原始代码进行任何更改。
ReubenThomas 的 bitlib 将用作此处的示例,因为它本身很小且没有外部依赖项。此处描述的步骤适用于大多数其他扩展。Bitlib 提供按位逻辑运算
需要什么
#include "lua.h" extern void lua_bitlibopen (lua_State *L); /* special functions for use with loadmodule.c */ int luaLM_import( lua_State *L ) { lua_bitlibopen(L); return 0; } const char * luaLM_version( void ) { return LUA_VERSION; }
; luabitlib.def: Declares the module parameters for the DLL. LIBRARY luabitlib DESCRIPTION 'Lua bitwise operations library' EXPORTS ; Explicit exports can go here luaLM_version @1 luaLM_import @2
现在,可以简单地将 luabitlib.dll 放在 Lua(启用 loadlib)可执行文件可以访问的路径中(同一个文件夹即可),并像这样加载它
>loadmodule("bitlib") using bitlib >a=5 >b=2 >print(imod(a,b)) -- returns the integer remainder of a divided by b 1
完整的源代码和 VC 项目文件可以从 [这里] 下载
注意:还有另一种创建库的便捷方法。如果您已经有了 .lib 文件,您只需要一个空的 dll 项目,其中包含该 lib、代理文件和 def 文件,将它们放在一起并构建,就完成了。