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

时间:2016-06-03 05:22:20

标签: lua 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中加载当前工作目录中的共享对象?

1 个答案:

答案 0 :(得分:2)

这是对的。原因是ffi.C指向命名空间以访问标准C运行时(以及一些额外的库,具体取决于您的操作系统)。来自LuaJIT文档:

  

这是默认的C库名称空间[...] - 请注意大写   'C'。它绑定到目标上的默认符号或库集   系统。这些或多或少与C编译器提供的相同   默认情况下,不指定额外的链接库。

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

  1. 声明要在ffi.cdef内使用的函数,因此LuaJIT知道如何使用 调用该功能。
  2. 导入外部库并将其分配给 一个Lua变量,用作外部的命名空间 功能
  3. 实际上调用该函数。
  4. 您的代码可以重写为:

    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
    

    <击>