按路径要求Lua中的自定义C模块

时间:2016-08-30 21:44:23

标签: lua torch

这是困扰我一段时间的问题。

在将自定义函数编写并编译到共享库之后,SASS_CSS := $(SASS_SRC:=.scss=.css) TS_JS := $(TS_SRC:.ts=.js) .PHONY: all js.stub all: $(SASS_CSS) $(TS_JS) %.css: %.scss $(SASS) $(SASS_FLAGS) $< > $@ $(TS_JS): %.js: %.ts js.stub $(TSLINT) $< js.stub: $(TS_SRC) $(TSC) $(TSC_FLAGS) $^ @touch $@ 仅在共享库与我调用它的脚本位于同一目录中时才有效。

尝试require('mylib')或类似绝对路径的任何努力都失败了。此外,通过相对路径“回溯”(即使用require('/path/to/mylib')也失败了。

那么如何指定..目录,或者共享库输出到何处?

2 个答案:

答案 0 :(得分:2)

根据Lua documentation on the require call(在这里使用Lua 5.2),加载器可以查找这些可加载模块。

似乎bin使用所谓的“搜索者”(上面链接的文档)来确定在哪里找到这些模块。总共有四个搜索者。来自文档:

  

第一个搜索者只是在package.preload中查找加载器   表

     

第二个搜索者使用。来查找装载程序作为Lua库   存储在package.path中的路径。搜索按照中所述完成   function package.searchpath。

     

第三个搜索者使用路径查找加载程序作为C库   由变量package.cpath给出。再次,搜索完成为   在函数package.searchpath中描述。例如,如果是C路径   是字符串require(),模块foo的搜索者将尝试打开文件"./?.so;./?.dll;/usr/local/?/init.so"./foo.so和   ./foo.dll,按此顺序排列。一旦找到C库,这个   搜索者首先使用动态链接工具链接应用程序   与图书馆。然后它试图在里面找到一个C函数   要用作加载器的库。这个C函数的名称是   字符串“luaopen_”与模块名称的副本连接在一起   每个点都用下划线代替。而且,如果模块名称   有一个连字符,它的前缀是(包括)第一个连字符   除去。例如,如果模块名称是a.v1-b.c,则为该函数   名字将是luaopen_b_c。

     

第四位搜索者尝试一体化装载机。它搜索C路径   用于给定模块的根名称的库。例如,   当需要a.b.c时,它将搜索一个C库。如果找到,   它调查了子模块的开放函数;在我们的   例如,那将是luaopen_a_b_c。有了这个设施,一个包   可以将几个C子模块打包到一个单独的库中   子模块保持其原有的开放功能。

对我们使用的搜索者是第三个:它用于任何共享库(.dll或.so),这通常是我们自定义C模块的构建方式。

使用模板字符串(带有问号的字符串),搜索者将查看每个指定的路径,用/usr/local/foo/init.so的参数代替问号。为了指定第三个搜索者的路径,必须设置(或追加)package.cpath,然后调用require()

所以也许您的目录结构为

require()

- ROOT |-lua |-bin 包含luascript.lua包含bin

要加载mylib.so,您只需在mylib.so中使用以下两行代码:

script.lua

注意:请注意分号。如果你追加(而不是上面的前缀),请确保在添加的路径上使用分号。它没有买违约。否则,您的新路径将合并到当前的默认路径,该路径仅为package.cpath = '/ROOT/bin/?.so;' .. package.cpath libfuncs = require('mylib')

答案 1 :(得分:-1)

如果您只是将系统配置为使用某个存储路径 那里的库最好的方法就是使用LUA_PATHLUA_CPATH env变量。 e.g。LUA_CPATH=/path/to/?.so。或者针对特定的Lua版本,例如LUA_CPATH_5_3=/path/to/?.so

但是如果你有一些库的完整路径,并且只是从这个目录加载这个特定的库,你可以使用package.loadlib函数。

local function loadlib(path, name)
  local sep = string.sub(package.config, 1, 1)
  local file = path .. sep .. name .. ((sep == '/') and '.so' or '.dll')
  local func = 'luaopen_' .. name
  local loader, msg = package.loadlib(file, func)
  assert(loader, msg)
  return assert(loader())
end

local mylib = loadlib([[/path/to]], 'mylib')