您的位置:首页 > 编程语言 > Lua

Lua模块化编程——使用require加载自己的dll模块

2012-05-30 11:05 381 查看
  Lua本身是一个轻量级的脚本语言,包含在Lua源码中的库功能通常相对单一,用户通常需要自己内嵌Lua解释器到自己的应用中,并且一个一个地将需要导出的函数导出给Lua使用。

  假如我们需要使用第三方的库,比如LuaFileSystem库——lfs、用于网络的Socket库或者计算Base64编码的库,除了找到其源码,并拷贝到自己的应用代码中之外,还有没有别的什么方式呢?

  大家都知道Windows DLL,这是一种动态链接的方式。Lua同样也支持这样一种模块加载的方式。你只需将所需的第三方库的DLL放到Lua的环境路径中——这个我暂时并不能穷举出具体有哪些,期待高人解答——或者简单地将其放入你的Lua解释器目录下。接着,在需要使用的脚本中,直接调用Lua的require函数,将DLL的名字去除扩展名作为参数,Lua就可以自动加载指定的DLL模块,并将其模块导出的内容打包到一个table中并返回。你可以使用一个全局的table来接收其引用。

  对于自己编写的模块,也可以采用相同的方式去编写。只需导出一个可以通过require加载的函数符号就可以了——require内部通过Windows API GetProcAddress来寻找其地址。这个函数的格式需要遵循Lua的模块标准,格式如下:

View Code

static int foo(lua_State *L)
{
lua_pushnumber(L, 1);
return 1;
}

static const struct lua_Reg modulename[] = {
{"foo", foo},
{NULL,NULL},
};

int luaopen_modulename(lua_State *L)
{
luaL_newlib(L, modulename); // 5.2之前使用luaL_register(L, "modulename", modulename);
return 1;
}


  Lua5.2修改了其导出模块的格式,大家要注意一下。

  当你在脚本中使用require加载一个模块xxx的时候,首先它会在Lua的环境路径中寻找以xxx命名的DLL,如果找到了,则会在这个DLL中寻找luaopen_xxx的函数用于加载模块。我们只需要将自己需要导出给Lua调用的C内容通过这个函数导出就可以了,具体方式可以查看Lua的源码,参考其math数学库luaopen_math的实现。使用起来确实相当方便。只不过要注意一下Lua5.2与之前版本的不兼容性——导出函数从LuaL_register变成了LuaL_newlib,虽然可以选择开启Lua5.2的兼容模式来继续使用LuaL_register,但我尝试的时候总是在Lua_checkversion的时候出错,提示说Multiple VMs detected。暂时来说,我是参考lfs库的实现方式,自己重定义宏LuaL_register。

  完整的示例我已经上传到GitHub中了,请用Visual Studio 2010查看其中的mylib工程,欢迎指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: