Skip to content

Add soluna.extlua for external C libs#81

Merged
cloudwu merged 1 commit intomasterfrom
extlua
Mar 11, 2026
Merged

Add soluna.extlua for external C libs#81
cloudwu merged 1 commit intomasterfrom
extlua

Conversation

@cloudwu
Copy link
Owner

@cloudwu cloudwu commented Mar 11, 2026

增加了运行时导入外部 C 库的方案。它解决的问题是:

在不修改 soluna 项目以及构建流程的基础上,可以在游戏项目中把需要的 Lua C 库单独编译为动态库,让 soluna 引擎可以在运行期动态加载。

方案的细节写在 https://blog.codingnow.com/2026/03/soluna_external_lib.html

使用以下命令可以构建 bin/sample.dll 用于测试脚本 test/extlua.lua 。

make extlua_sample

注:luamake 脚本没有给这个编译目标,在游戏项目中编译额外的 C 库建议按需写构建脚本。只需要额外链接 extlua/extlua.c

@yuchanns 我不太清楚 wasm 下的动态库如何使用,你研究一下?

@cloudwu cloudwu merged commit 06c7693 into master Mar 11, 2026
5 checks passed
@yuchanns
Copy link
Contributor

你好像没有提交 test/extlua.lua?

cloudwu added a commit that referenced this pull request Mar 11, 2026
@cloudwu
Copy link
Owner Author

cloudwu commented Mar 11, 2026

我猜想 wasm 版本的动态库可能还需要额外的部署流程?

不知道有没有可能从内存加载 .wasm 文件,如果可以就能从 zip 包里读出来加载了。不过本地版应该难以做到把 .dll/.so 打包到 zip 包中。

@yuchanns
Copy link
Contributor

emscripten 支持侧载 wasm 动态库: https://emscripten.org/docs/compiling/Dynamic-Linking.html

具体怎么做我晚点看看。

这个功能挺好的,可以做到分包加载,对于一些限制 wasm 大小的场景,比如微信小程序,可以考虑把 soluna 本体也拆成多个 wasm 分包加载。(没做过微信小游戏,不知道对 wasm 加载限制多少,目前会不会限制。只是今天看到 discussion 有人发问正好联想到)

@cloudwu
Copy link
Owner Author

cloudwu commented Mar 11, 2026

鉴于 sokol 的 shader 机制,这可能是最合适的外挂 shader (材质) 的方式。因为 sokol 想把额外的 shader 放在数据文件中极不方便。

不过,要做外挂材质,还需要把必要的 sokol api 也导出。

@cloudwu
Copy link
Owner Author

cloudwu commented Mar 11, 2026

目前,动态库的加载利用的是 lua 代码中原本就有的 package.loadlib ,它调用的是 dlopen ,所以如果 emscripten 本身把 dlopen 模拟对了就不用做什么工作。可能只需要完善发布流程。

@cloudwu cloudwu deleted the extlua branch March 11, 2026 10:11
@yuchanns
Copy link
Contributor

yuchanns commented Mar 11, 2026

我在分支上已经做了处理,构建上去看起来没报错但是加载会卡住没有任何输出。突然想到上次做 wasm worker 特性的时候,发现 io 必须在主线程。所以这种 dlopen dylib 的行为应该也会有问题。因为 start.lua 不是在主线程 想了下可能也不是 io 问题毕竟 pthread 代理了。还得明天再排查看看

@cloudwu
Copy link
Owner Author

cloudwu commented Mar 12, 2026

在 preload 分支上 修改了一下,增加了 preload ext libs 功能,它在启动 ltask 前预加载动态库。6fdb564

预加载库的列表写在 settings 里,这也可以保证 dlopen 都发生在主线程。另外还可以在每个服务按需 require 扩展 C 模块(旧实现是把这些 C 模块全部 require 一次)。

可以用 bin/soluna test/extlua.game 测试。

有了这个功能,就可以去掉 soluna.extlib() 了。如果还是想动态加载,依然可以调用 soluna.extlua.load() 来完成。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants