如何使用Lua-lanes调用内存加载的C实现App模块的函数
Lua Lanes调用内存嵌入C模块的解决方案
报错根因
你遇到的两类报错原因如下:
- 写法(1)报错:Lanes创建的每个工作线程对应独立的Lua State,主线程设置的
package.preload['App']、全局App变量默认不会同步到子线程环境,子线程加载App模块时找不到对应预加载逻辑,就会尝试从文件系统查找,最终触发找不到模块的报错。 - 写法(2)报错:
lanes.gen的第一个参数是指定子线程需要导入的Lua标准库名称(如base/os/math等),App不属于Lua标准库,因此会报库名非法错误。
可行解决方案
方案1:通过preload参数向子线程注入预加载逻辑
不需要修改C侧代码,仅调整Lua侧逻辑,直接把主线程的App模块预加载函数传递给子线程即可,全程走内存加载:
-- 子线程函数内先require App再调用 local function thread1(n) local App = require 'App' return App.get_appinfo(n) end function startlanes() local lanes = require 'lanes' -- 主线程侧注册App预加载逻辑 package.preload['App'] = function() return App end package.loaded['App'] = App -- 生成线程函数时通过preload参数把预加载逻辑同步给子线程 local f = lanes.gen('*', { preload = { App = package.preload['App'] } }, thread1) local res = f(1) -- 等待线程执行完成获取返回值 res:join() print(res[1]) end
方案2:直接传递全局App表(适用于无状态只读C模块)
如果你的App表中所有C函数都是线程安全、无主线程私有状态依赖,可以直接把App表作为全局变量传递给子线程,不需要走模块加载逻辑:
-- 子线程直接用全局App即可 local function thread1(n) return App.get_appinfo(n) end function startlanes() local lanes = require 'lanes' -- 生成线程函数时通过globals参数把App表同步给子线程 local f = lanes.gen('*', { globals = {App = App} }, thread1) local res = f(1) res:join() print(res[1]) end
注意事项
- 确保C侧实现的
get_appinfo是线程安全的,没有绑定主线程专属的用户数据、全局变量等状态,否则跨线程调用会出现异常甚至崩溃。 - 跨线程传递的表默认是深拷贝,子线程中修改
App表不会同步回主线程。
内容的提问来源于stack exchange,提问作者vvkatwss vvkatwss
相关产品推荐
相关产品推荐

