创建一个可以被 Lua 加载的 C++ DLL(动态链接库)

我有一个小应用程序,它使用链接为 dll 的 Lua(非静态)。我想使用 package.loadlib (libname,funcname) 通过 Lua 加载我自己编写的 C ++-编写的 dll。为此,我需要导出遵循 Lua 的 lua_CFunction 协议的函数。显然,为此,我必须将 lua.h 合并到我的项目中,并使用 Lua 的函数传递参数和结果。所以我的问题是:

  1. 我的 DLL 是否使用已加载到小型应用程序进程中的 Lua dll?
  2. package.loadlib 是否立即加载和卸载我的 DLL,还是我的 DLL 一旦加载就一直存在,直到 lua 脚本执行结束或应用程序终止?

原文链接 https://stackoverflow.com/questions/3575803

点赞
stackoverflow用户298661
stackoverflow用户298661

你可以动态地链接到与应用程序相同的 Lua dll。

至于package.loadlib,我不知道它是如何工作的。阅读源代码?

2010-08-26 14:01:57
stackoverflow用户68204
stackoverflow用户68204

以下是根据你的具体问题撰写的回答:

  1. 是的,但前提是你的 DLL 必须是隐式链接的。要小心处理这一点,因为如果你意外地将两个 Lua VM 链接到应用程序中,这可能会导致极大的混乱。同样的问题也适用于 C 运行时。我建议你使用 Dependency Walker 加载整个应用程序,以验证它只引用了一个 Lua DLL 和一个单独的 C 运行时。

  2. 我的理解是,package.loadlib() 只负责加载并链接到指定库中的指定函数。只要返回的函数对象(表示你所命名的 lua_CFunction)存在,那么这个 DLL 一定被加载了。如果你失去了对该函数的最后一个引用,则该库可能被垃圾回收,并且如果被回收,它将被卸载。在 Lua-L 邮件列表中曾经有过关于如何确保特定的 DLL 被卸载的讨论。否则,如果你只是假设只要你能访问它所存储的函数就说明 DLL 被加载了,你就没问题了。

不过我想补充说明,使用建立在此之上的模块系统是一种更好的方式,用来扩展 Lua 的 C 或 C++ 代码。《Lua 编程》第 26 章对此进行了更详细的描述,并且该链接引导你浏览第一版(描写 Lua 5.0)的在线副本。请注意,模块系统在 Lua 5.1、Lua 5.2 中都发生了一些变化。获得《Lua 编程》第二版或第三版(这两个版本都可通过许多书店以纸质和电子书的形式获取)可能会对你有所帮助。

这里是一份简要总结:你可以在 C 中创建一个名为 foo 的模块,创建 foo.dll 并导出至少一个具有原型 int luaopen_foo(lua_State *L) 的函数。该函数应加载你的模块(通常使用 luaL_register() 在 Lua 5.1 中,或使用 luaL_newlib()luaL_setfuncs() 在 Lua 5.2 中来注册一个充满 C 函数的表)并返回该表。在 Lua 代码中,你需要将 DLL 放在 package.cpath 中描述的路径上,然后可以通过 local foo = require "foo" 这样的代码来加载它。各个 Lua 5.x 版本之间还存在其他微小的差异,但相对而言,创造适用于任何 Lua 5.x 版本的 C 代码是相对简单的。

使用这种方法,你的优势是可以通过路径加载模块,可以写入 C 或 Lua 或二者混合的组合,可以很好地与其他模块共存。使用单个 require 调用就可以加载您需要的多个 C 函数或仅加载你需要的少数 C 函数。

2010-08-26 21:27:49