Luajit 从当前工作目录而不是默认搜索路径加载共享对象
Luajit load shared object from current working directory instead of default search path
我在 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 中加载当前工作目录中的共享对象?
没错。原因是 ffi.C
指向一个命名空间以访问标准 C 运行时(加上一些额外的库,具体取决于您的 OS)。来自 LuaJIT 文档:
This is the default C library namespace [...] — note the uppercase
'C'. It binds to the default set of symbols or libraries on the target
system. These are more or less the same as a C compiler would offer by
default, without specifying extra link libraries.
如果您想从外部库调用 C 函数,您需要:
- 在
ffi.cdef
中声明要使用的函数,因此 LuaJIT 知道如何
调用该函数。
- 导入外部库并赋值给
一个 Lua 变量,用作外部的命名空间
功能。
- 实际调用函数。
您的代码可以改写为:
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
我在 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 中加载当前工作目录中的共享对象?
没错。原因是 ffi.C
指向一个命名空间以访问标准 C 运行时(加上一些额外的库,具体取决于您的 OS)。来自 LuaJIT 文档:
This is the default C library namespace [...] — note the uppercase 'C'. It binds to the default set of symbols or libraries on the target system. These are more or less the same as a C compiler would offer by default, without specifying extra link libraries.
如果您想从外部库调用 C 函数,您需要:
- 在
ffi.cdef
中声明要使用的函数,因此 LuaJIT 知道如何 调用该函数。 - 导入外部库并赋值给 一个 Lua 变量,用作外部的命名空间 功能。
- 实际调用函数。
您的代码可以改写为:
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