创建Lua可加载的C ++ DLL

时间:2010-08-26 13:57:31

标签: c++ c dll lua

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

  1. 我的DLL会使用已加载到小应用程序进程中的Lua dll吗?
  2. package.loadlib是否会立即加载和卸载我的DLL,或者我的DLL一旦加载仍然存在,直到最后lua scrpit执行或应用程序终止?

2 个答案:

答案 0 :(得分:8)

从您的具体问题开始:

  1. 是的,但前提是您的DLL与其隐式链接。请注意这一点,因为如果您不小心将Lua VM的两个副本链接到您的应用程序中,这可能会造成很大的混乱。就此而言,类似的问题也适用于C运行时。我会在Dependency Walker下加载整个应用程序,以验证它只引用一个Lua DLL实例和一个C运行时。

  2. 我的理解是package.loadlib()仅负责加载和链接到指定库中的命名函数。只要返回的函数对象(表示您命名的lua_CFunction)是活动的,那么DLL肯定会被加载。如果您丢失了对该函数的最后一个引用,那么该库可用于垃圾收集,如果收集它将被卸载。在Lua-L邮件列表中已经谈到了如何保证特定DLL被卸载,如果这是您关注的话。否则,如果您只是假设DLL已加载,只要您可以访问存储在其中的函数,您就可以了。

  3. 让我补充说,基于此构建的模块系统是使用C或C ++代码扩展Lua的更好方法。 Chapter 26 of Programming in Lua更详细地描述了这一点,链接是第一版在线副本中的那一章(描述了Lua 5.0)。请注意,模块系统在Lua 5.1中确实有所改变,在Lua 5.2中也是如此。获取PiL第二版或第三版的副本(通过许多书商提供纸质和电子书形式)可能会有所帮助。

    以下是执行摘要:要在C中创建名为foo的模块,您需要创建foo.dll,它至少导出一个带有原型int luaopen_foo(lua_State *L)的函数。该函数应该加载您的模块(通常使用Lua 5.1中的luaL_register()或Lua 5.2中的luaL_newlib()luaL_setfuncs()来注册一个充满C函数的表)并返回该表。在Lua端,您将DLL放在package.cpath中描述的路径上的某个位置,然后可以通过local foo = require "foo"之类的代码加载它。各种Lua 5.x版本之间还有其他细微差别,但创建可以为其中任何一个编译的C代码相对简单。

    以这种方式做事,您的优势在于可以从路径加载模块,可以用C或Lua或两者混合编写模块,并且可以很好地与其他模块一起使用。您还可以通过require的单次调用来加载所需数量的C函数。

答案 1 :(得分:-1)

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

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