我有一个小应用程序,使用Lua链接为DLL(非静态).我想使用package.loadlib(libname,funcname)通过Lua加载我自己的c ++编写的dll .为此,我需要导出一个遵循Lua的lua_CFunction协议的函数.显然,由于这个原因,我必须将lua.h我的项目合并到Lua的函数中以传递参数和结果.所以我的问题是:
package.loadlib立即加载和卸载我的DLL或我的DLL一旦加载仍然保持到最后lua scrpit执行或应用程序终止?从您的具体问题开始:
是的,但仅当您的DLL隐式链接到它时.请注意这一点,因为如果您不小心将Lua VM的两个副本链接到您的应用程序中,这可能会造成很大的混乱.就此而言,类似的问题也适用于C运行时.我将在Dependency Walker下加载整个应用程序,以验证它只引用Lua DLL的一个实例和一个C运行时.
我的理解是,package.loadlib()它只负责加载和链接到命名库中的命名函数.只要返回的函数对象(代表lua_CFunction您的名字)是活动的,那么DLL肯定会被加载.如果您丢失了对该函数的最后一个引用,那么该库可用于垃圾收集,如果收集它将被卸载.在Lua-L邮件列表中已经谈到了如何保证特定DLL被卸载,如果这是您关注的话.否则,如果您只是假设DLL已加载,只要您可以到达存储在其中的函数,您就可以了.
让我补充说,基于此构建的模块系统是使用C或C++代码扩展Lua的更好方法.Lua中编程的第26章更详细地描述了这一点,链接是第一版在线副本中的那一章(描述了Lua 5.0).请注意,模块系统在Lua 5.1中确实有所改变,在Lua 5.2中也是如此.获取PiL的第二版或第三版(通过许多书商提供纸质和电子书形式)的副本可能会有所帮助.
这是一个执行摘要:要创建一个以fooC 命名的模块,您可以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版本之间存在其他细微差别,但创建可以为其中任何一个编译的C代码相对简单.
通过这种方式做事,您的优势在于可以从路径加载模块,可以用C或Lua或两者混合编写模块,并且可以很好地与其他模块一起使用.您还可以通过单次调用来加载所需数量的C函数require.