Calling Library in Lua

2020-07-18 07:48发布

问题:

I have created a Wireshark dissector in Lua for an application over TCP. I am attempting to use zlib compression and base64 decryption. How do I actually create or call an existing c library in Lua?

The documentation I have seen just says that you can get the libraries and use either the require() call or the luaopen_ call, but not how to actually make the program find and recognize the actual library. All of this is being done in Windows.

回答1:

You can't load any existing C library, which was not created for Lua, with plain Lua. It's not trivial at least.

*.so/*.dll must follow some specific standard, which is bluntly mentioned in programming in Lua#26.2 and lua-users wiki, code sample. Also similar question answered here.

There are two ways You could solve Your problem:

  1. Writing Your own Lua zlib library wrapper, following those standards.
  2. Taking some already finished solution:
    • zlib@luapower
    • lua-zlib
  3. ffi

Bigger list @lua-users wiki

The same applies to base64 encoding/decoding. Only difference, there are already plain-Lua libraries for that. Code samples and couple of links @lua-users wiki.

NOTE: Lua module package managers like LuaRocks or LuaDist MIGHT save You plenty of time.

Also, simply loading a Lua module usually consists of one line:

local zlib = require("zlib")

The module would be searched in places defined in Your Lua interpreter's luaconf.h file.

For 5.1 it's:

#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


回答2:

How do I actually create or call an existing c library in Lua?

An arbitrary library, not written for use by Lua? You generally can't.

A Lua consumable "module" must be linked against the Lua API -- the same version as the host interpreter, such as Lua5.1.dll in the root of the Wireshark directory -- and expose a C-callable function matching the lua_CFunction signature. Lua can load the library and call that function, and it's up to that function to actually expose functionality to Lua using the Lua API.

Your zlib and/or base64 libraries know nothing about Lua. If you had a Lua interpreter with a built-in FFI, or you found a FFI Lua module you could load, you could probably get this to work, but it's really more trouble than it's worth. Writing a Lua module is actually super easy, and you can tailor the interface to be more idiomatic for Lua.

I don't have zlib or a base64 C library handy, so for example's sake lets say we wanted to let our Lua script use the MessageBox function from the user32.dll library in Windows.

#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;
}

To build this, we need to link against user32.dll (contains MessageBox) and lua5.1.dll (contains the Lua API). You can get Lua5.1.lib from the Wireshark source. Here's using Microsoft's compiler to produce messagebox.dll:

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

Now your Lua scripts can write:

require "messagebox"

msgbox("Hello, World!")


回答3:

Your only option is to use a library library like alien. See my answer Disabling Desktop Composition using Lua Scripting for other FFI libraries.



标签: lua