Luajit 从当前工作目录中加载共享对象而不是默认搜索路径

我正在Ubuntu 16.04上使用Luajit 2.0.4

我有一个简单的C库。

int five() {
    return 5;
}

我像这样编译它

gcc -o five.so -shared -fPIC -Wall -Werror five.c

在同一目录下,我有一个Lua脚本

local ffi = require("ffi")

ffi.load("./five.so")

ffi.cdef([[
int five();
]])

print(ffi.C.five())

我也尝试过使用绝对路径。

local ffi = require("ffi")

local fh = assert(io.popen("pwd", "r"))
local cwd = assert(fh:read())

print(cwd)

ffi.load(cwd .. "/five.so")

ffi.cdef([[
int five();
]])

print(ffi.C.five())

当我运行

luajit five.lua

我得到了这个

luajit: five.lua:6: luajit: undefined symbol: five
stack traceback:
        [C]: in function '__index'
        five.lua:6: in main chunk
        [C]: at 0x004044a0

如何在luajit中加载当前工作目录中的共享对象?

点赞
用户134758
用户134758

没错。原因是 ffi.C 指向一个命名空间,用于访问标准 C 运行时(再加上一些其他库,取决于你的操作系统)。根据 LuaJIT 的文档:

这是默认的 C 库命名空间[...] 注意大写字母 'C'。它绑定到目标系统上的默认符号或库集。这些符号或库与 C 编译器默认提供的几乎相同,没有指定额外的链接库。

如果你想从外部库调用 C 函数,你需要:

  1. ffi.cdef 内声明要使用的函数,这样 LuaJIT 就知道如何调用该函数。
  2. 导入外部库并将其分配给 Lua 变量,它将用作外部函数的命名空间。
  3. 实际调用函数。

你的代码可以改写为:

local ffi = require("ffi")

local lib = ffi.load("five")

ffi.cdef([[
   int five();
]])

print(lib.five())

此外,不需要添加 .os 后缀。为了解析库名称,使用了 package.cpath 变量。它的工作原理类似于 package.path 变量。问号(?)会被库名称替换。

$ luajit -e "print(package.cpath)"
./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so
2016-06-18 21:42:52