二进制模块教程 |
|
版本说明:本页面涉及较早版本的 Lua(4.0 和 5.0 beta),使用了 `loadmodule` 扩展。Lua 5.1 使用 `package.loadlib` 和 `require`。Lua 5.0 使用 `loadlib`。)
本页面的目标是展示如何轻松地从现有的 Lua 扩展创建 LuaBinaryModules,而无需更改相关扩展的原始源代码 - MartinSpernau
目标: 将一个现有的 Lua 扩展(最初是静态链接到 Lua 可执行文件)编译成动态链接库,以便通过 LuaBinaryModules 中描述的 loadmodule() 功能在运行时加载。
特殊目标: 不更改原始代码(很可能由其他人编写)
讨论: Lua 扩展通常包含一组源文件和头文件,用于实现所需的功能。这些函数通过特殊的包装函数对 Lua 解释器可用,并且有一个 'open' 函数用于将这些函数 '注册' 到当前的 Lua 状态中。(这方面的讨论可以在 Lua 参考手册和 BindingCodeToLua 中找到)
loadmodule 功能(LuaBinaryModules)利用了一个事实,即每个扩展基本上只有一个 'open'-函数。由于这些函数可以具有因扩展而异的名称(例如,lua_bitlibopen,lua_fooinizialize 等),loadmodule 模块将库打开代码封装到一个名为 luaLM_import 的已定义函数中。它还定义了 luaLM_version,这对于检查扩展与核心 Lua 库的版本兼容性是必需的。
这两个函数现在作为要编译的动态链接库的唯一外部入口点。当从 Lua 调用 loadmodule('modname') 时,它将尝试加载该扩展的 DLL(在 Windows 上是 lua**modname**.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 项目文件可在此处下载:[here]
注意:还有一种创建库的便捷方法。如果您已经有了 .lib 文件,您只需要一个空的 DLL 项目,其中包含该 lib、代理文件和 def 文件,将它们放在一起并构建,就可以了。