在Lua中调用库函数

我已经使用 Lua 在 Wireshark 中创建了一个 TCP 应用程序识别器。我尝试使用 zlib 压缩和 base64 解密。我应该如何在 Lua 中创建或调用现有的 C 库呢?

我看到的文档只是说你可以获取库并使用 require() 调用或 luaopen_ 调用,但没有告诉我如何让程序找到和识别实际的库。所有这些都是在 Windows 上进行的。

点赞
用户1150918
用户1150918

你不能用纯 Lua 来加载任何未为 Lua 创建的现有 C 库。至少不是一件简单的事情。

*.so/*.dll必须遵循某些特定的标准,这些标准在 编程 Lua#26.2lua-users wiki代码示例 中被简单提到。也有类似问题的解答在 这里

有两种方法可以解决您的问题:

  1. 编写符合这些标准的自己的 Lua zlib 库包装器。
  2. 采用一些已经完成的解决方案:
  3. ffi

更多列表请参见 @lua-users wiki

同样适用于 base64 编码/解码。唯一不同的是,已经有纯 Lua 库了。该 @lua-users wiki 上提供了代码示例和几个链接。

注意: Lua 模块包管理器例如 LuaRocksLuaDist 可能可以节省您大量时间。

另外,简单加载 Lua 模块通常只包括一行:

local zlib = require("zlib")

该模块将在定义在您的 Lua 解释器的 luaconf.h 文件中的位置中搜索。

对于 5.1,它是:

#if defined(_WIN32)
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR        "!\\lua\\"
#define LUA_CDIR        "!\\"
#define LUA_PATH_DEFAULT  \
            ".\\?.lua;"  LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
                         LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua"
#define LUA_CPATH_DEFAULT \
    ".\\?.dll;"  LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"

#else
2014-03-17 15:59:41
用户501459
用户501459

如何在 Lua 中创建或调用现有的 C 库?

对于不是为 Lua 编写的任意 C 库,一般不能直接调用。

一个可供 Lua 使用的“模块”必须链接到 Lua API,与宿主解释器版本相同,例如 Wireshark 目录的根目录中的 Lua5.1.dll, 并公开与 lua_CFunction 签名匹配的可从 C 调用的函数。Lua 可以加载库并调用该函数,而该函数负责使用 Lua API 实际暴露功能给 Lua。

你的 zlib 和 / 或 base64 库对 Lua 一无所知。 如果你有一个内置 FFI 的 Lua 解释器,或者你找到了一个可以加载的 FFI Lua 模块,你可能可以让它工作,但这真的不值得一试。编写 Lua 模块实际上非常容易,你可以将接口量身定制为适合 Lua 的习惯用法。

举个例子,我们想让我们的 Lua 脚本使用 Windows 的 user32.dll 库中的 MessageBox 函数,但我没有 zlib 或 base64 C 库。

#include <windows.h>
#include "lauxlib.h"

static int luaMessageBox (lua_State* L) {
    const char* message = luaL_checkstring(L,1);
    MessageBox(NULL, message, "", MB_OK);
    return 0;
}

int __declspec(dllexport) __cdecl luaopen_messagebox (lua_State* L) {
    lua_register(L, "msgbox", luaMessageBox);
    return 0;
}

要构建它,我们需要链接到 user32.dll(包含 MessageBox)和 lua5.1.dll(包含 Lua API)。您可以从 Wireshark 源中获得 Lua5.1.lib。这里是使用 Microsoft 的编译器生成 messagebox.dll

cl /LD /Ilua-5.1.4/src messagebox.c user32.lib lua5.1.lib

现在你的 Lua 脚本可以这样写:

require "messagebox"

msgbox("Hello, World!")
2014-03-17 18:50:25
用户869951
用户869951

你唯一的选择是使用类库 alien,参见我的答案使用 Lua 脚本禁用桌面组成了解其他FFI类库。

2014-03-17 21:30:26