如何创建一个Lua插件,调用C Lua API?

我在编写的 Lua 插件中遇到了错误,这些错误的症状表明将两个副本的 Lua 运行时链接在一起,详见此信息: http://lua-users.org/lists/lua-l/2008-01/msg00671.html

引用:

这反过来意味着 dummynode 的等式测试失败了。 如果将 Lua 核心的两个副本链接到应用程序中,或惹出两个 dummynode 实例,这就是通常的症状。

常见错误是将 C 扩展模块(共享库)与静态库链接起来。对于扩展模块的链接器命令行绝不能包含 -llua 或类似的东西!

只有包含 Lua 核心本身的可执行程序才能导出 Lua 核心符号(如 lua_insert() 等)。之后加载的所有 C 扩展模块都可以访问这些符号。在 ELF 系统上,这就是链接器行上 -Wl,-E 的作用。 MACH-O 系统不需要,因为所有非静态符号都被导出。

这正是我看到的错误……但我不知道应该做些什么。

我已经将 lua src 目录添加到 DLL 的 include 路径中,它是我的 Lua 插件的 C 组件,但当我链接它时,我会得到一堆错误,如下所示:

 Creating library file: libmo.dll.a
 CMakeFiles/moshared.dir/objects.a(LTools.c.obj): In function `moLTools_dump':
 d:/projects/mo-pong/deps/mo/src/mo/lua/LTools.c:38: undefined reference to `lua_gettop'
 d:/projects/mo-pong/deps/mo/src/mo/lua/LTools.c:47: undefined reference to `lua_type'
 d:/projects/mo-pong/deps/mo/src/mo/lua/LTools.c:48: undefined reference to `lua_typename'
 d:/projects/mo-pong/deps/mo/src/mo/lua/LTools.c:49: undefined reference to `lua_tolstring'

因此,总结一下我的情况:

  1. 父二进制文件静态链接到 Lua 运行时。

  2. Lua 库加载包含 C 代码的 DLL。

  3. DLL 中的 C 代码需要调用 Lua C API(例如 lua_gettop())

该如何链接它?肯定动态库无法“看到”父二进制文件中的符号,因为父二进制文件不会从 DLL 中加载符号,它们是静态链接的。

……但是,如果我将这些符号作为插件的一部分链接,我会得到上面的错误。

求助?这似乎是一个经常出现的问题(dll 依赖于父二进制文件中的符号,如何链接它?),但我似乎找不到任何有用的线程。

(在你询问之前,不,我无法控制父二进制文件,也无法让它从 DLL 中加载 Lua 符号)

点赞
用户1034226
用户1034226

最好使用 libtool 来使你的链接更加容易和可移植。可执行文件需要用 -export-dynamic 进行链接,以导出其中的所有符号,包括来自静态库的 Lua 符号。之后,模块需要使用 -module -shared -avoid-version 进行链接,在 Windows 平台上,还需额外使用 -no-undefined;在 MacOS 上,还需要额外使用 -no-undefined -flat_namespace -undefined suppress -bundle;而 Linux 和 FreeBSD 不需要其他符号。这将使模块留下未定义的符号,在父模块中得到满足。如果有任何缺失,模块将无法被父模块 dlopen

由于每个环境的语义略有不同,因此可能需要进行某些调整。有时标志的顺序很重要。再次提醒,建议使用 libtool,因为它隐藏了许多不一致性。

2012-07-15 14:53:22