手动使用C/C++编写Lua扩展插件

最近在研究如何在Windows 下嵌入Lua来完成业务模块编写的时候 发现Lua的一些问题,首先Lua作为一门脚本语言,其灵活性和可扩展性是很高的,要不然Cocos2d-x中也不会嵌入他来编写业务逻辑,但是由于国内资料相当的少,很少有人去正八经研究完了之后 写一篇文章 来分享自己的成果,想要去深入理解应用一些东西得时候,显得很无力,很多Lua扩展都是直接写扩展库来完成,如果不理解原理甚至你都不会灵活运用,这就是本文写作的目的。

第一 我需要Lua嵌入我的应用程序,这一点很容易的做到。

第二 我需要使用Lua进行数据层的操作,我希望有一个类似 Java PHP中的ORM框架来完成我的Sqlite3数据库操作,但是研究来研究去发现 好坑爹,只有下面两个库还算可以。 LuaSql 已经好几年没有更新了,Github上最新的代码 都是基于Sqlite3以及Lua5.1之前的版本,另一个lsqlite3也是 ,虽然相对强悍些 ,但是 貌似文档上说 只在Linux下测试通过。。。所以面对这些坑爹问题的时候 去勉强编译这些古老的代码还不如 自己去根据sqlite3编写自己的Lua 扩展。

下面进入正题:

一步一步编写自己的Lua扩展程序,到此我假设大家已经具有Lua嵌入开发的基础 。

首先新建我们自己的DLL项目作为Lua扩展库,设置好Lua库的路径 ,头文件包含路径,之后 在扩展库项目源文件中添加入下代码        用作Lua初始化 。

[cpp]  view plain  copy
 print ?
  1. extern "C"  
  2. {  
  3. #include "lua.h"  
  4. #include "lualib.h"  
  5. #include "lauxlib.h"  
  6. };  
  7. ///打开Lua Libs  
  8. lua_State *GetLua()  
  9. {  
  10.     lua_State *lua=luaL_newstate() ;  
  11.     luaL_openlibs(lua);  
  12.     return lua;  
  13. }  
如下图



第二步骤编写 Lua 扩展原型 我这里 使用的是 兼容Lua5.1扩展方式,那么 请在Lua库以及 我们的扩展库项目添加这样我们可以使用 Lua5.1方式来扩展Lua,

当然我们也可以使用Lua5.2最新方式进行扩展 不过这都无所谓了。

下面告诉编译器 我使用 5.1兼容扩展生成 DLL共享库。

[cpp]  view plain  copy
 print ?
  1. #define LUA_COMPAT_MODULE  
  2. #define LUA_CORE  
  3. #define LUA_BUILD_AS_DLL  
这个时候我么开始按照Lua的方式来编写我们的扩展库。。可以有两种方式

第一种内嵌式扩展就是直接 将扩展写到我们的应用程序中,我们开发的时候通常这么做。 而不是DLL中,代码如下 。

[cpp]  view plain  copy
 print ?
  1. #define LUA_COMPAT_MODULE  
  2. extern "C"  
  3. {  
  4. #include "lua.h"  
  5. #include "lualib.h"  
  6. #include "lauxlib.h"  
  7. };  
  8. ///打开Lua Libs  
  9. lua_State *GetLua()  
  10. {  
  11.     lua_State *lua=luaL_newstate() ;  
  12.     luaL_openlibs(lua);  
  13.     return lua;  
  14. }  
  15.   
  16. static int extFunc(lua_State* L)    
  17. {    
  18.     printf("i am a embed Lua Extension By Programmer小卫!\n");    
  19.     return 0;    
  20. }    
  21. const luaL_Reg reg[]=  
  22. {  
  23.     {"func",extFunc},  
  24.     {NULL, NULL}  
  25. };   
  26. LUALIB_API int luaopen_usher_luaex(lua_State *L)    
  27. {    
  28.     //lua 函数  
  29.   
  30.     luaL_openlib(L, "usher", reg, 0);  
  31.     return 0;//没有返回值  
  32. }  
  33. int _tmain(int argc, _TCHAR* argv[])  
  34. {    
  35.     lua_State *lua=GetLua();  
  36.     luaopen_usher_luaex(lua);  
  37.     if(0!=luaL_dofile(lua,"./luaext.lua")){  
  38.         printf("load error!\n");  
  39.     }  
  40.     return 0;  
  41. }  
Lua测试代码如下

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. require("usher")  //<span style="color:#FF0000;">关于require加载机制 在后续讲解</span>  
  2. usher.func()  


第二种 插件式扩展我们用到的好多第三方Lua扩展就是按照此种方式开发DLL扩展

代码如下:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #define LUA_COMPAT_MODULE  
  2. extern "C"  
  3. {  
  4. #include "lua.h"  
  5. #include "lualib.h"  
  6. #include "lauxlib.h"  
  7. };  
  8.   
  9. lua_State *GetLua()  
  10. {  
  11.     lua_State *lua=luaL_newstate() ;  
  12.     luaL_openlibs(lua);  
  13.     return lua;  
  14. }  
  15.   
  16. static int extFunc(lua_State* L)    
  17. {    
  18.     printf("i am a Lua Extension By Programmer小卫!");    
  19.     return 0;    
  20. }    
  21. static const luaL_Reg reg[]=  
  22. {  
  23.     {"func",extFunc},  
  24.      {NULL, NULL}  
  25. };   
  26. //模块名字 dll名字  
  27. //被加载器加载  
  28.  extern "C" _declspec(dllexportint luaopen_usher_luaex(lua_State *L)    
  29. {    
  30.     //lua 函数  
  31.   
  32.     luaL_openlib(L, "usher", reg, 0);  
  33.     return 0;//没有返回值  
  34. }  
  35. BOOL WINAPI DllMain(  
  36.     __in  HINSTANCE hinstDLL,  
  37.     __in  DWORD fdwReason,  
  38.     __in  LPVOID lpvReserved  
  39.     )  
  40. {  
  41.   
  42.     return TRUE ;  
  43. }  
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. //lua插件调用代码如下  
  2. require("usher.luaex")  //加载当前package.cpath下的usher\luaex.dll 插件 并且 加载入口函数从而加载 lua扩展库  
  3. usher.func()  


便已生成的dll我们可以发现         导出了如下函数 luaopen_usher_luaex用给lua模块进行加载

生成的扩展模块dll如下


最终运行结果如下




好了到现在开始你也可以为Lua 写 扩展库了,下一张详细分析Lua的 require 包含机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值