程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 手動使用C/C++編寫Lua擴展插件

手動使用C/C++編寫Lua擴展插件

編輯:C++入門知識

手動使用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初始化 。

extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
///打開Lua Libs
lua_State *GetLua()
{
	lua_State *lua=luaL_newstate() ;
	luaL_openlibs(lua);
	return lua;
}
如下圖

vcq9vfjQ0MCp1bkgsru5/dXitrzO3sv5zr3By6GjPC9zdHJvbmc+PC9wPgo8cD48c3Ryb25nPs/Cw+a45svfseDS68b3IM7SyrnTwyA1LjG85sjdwKnVucn6s8kgRExMubLP7b/ioaM8L3N0cm9uZz48YnI+CjwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">#define LUA_COMPAT_MODULE #define LUA_CORE #define LUA_BUILD_AS_DLL這個時候我麼開始按照Lua的方式來編寫我們的擴展庫。。可以有兩種方式

第一種內嵌式擴展就是直接 將擴展寫到我們的應用程序中,我們開發的時候通常這麼做。 而不是DLL中,代碼如下 。

#define LUA_COMPAT_MODULE
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
///打開Lua Libs
lua_State *GetLua()
{
    lua_State *lua=luaL_newstate() ;
    luaL_openlibs(lua);
    return lua;
}

static int extFunc(lua_State* L)  
{  
    printf("i am a embed Lua Extension By Programmer小衛!\n");  
    return 0;  
}  
const luaL_Reg reg[]=
{
    {"func",extFunc},
    {NULL, NULL}
}; 
LUALIB_API int luaopen_usher_luaex(lua_State *L)  
{  
    //lua 函數

    luaL_openlib(L, "usher", reg, 0);
    return 0;//沒有返回值
}
int _tmain(int argc, _TCHAR* argv[])
{  
    lua_State *lua=GetLua();
    luaopen_usher_luaex(lua);
    if(0!=luaL_dofile(lua,"./luaext.lua")){
        printf("load error!\n");
    }
    return 0;
}

Lua測試代碼如下

require("usher")  //關於require加載機制 在後續講解
usher.func()
\

第二種 插件式擴展我們用到的好多第三方Lua擴展就是按照此種方式開發DLL擴展

代碼如下:

#define LUA_COMPAT_MODULE
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};

lua_State *GetLua()
{
	lua_State *lua=luaL_newstate() ;
	luaL_openlibs(lua);
	return lua;
}

static int extFunc(lua_State* L)  
{  
	printf("i am a Lua Extension By Programmer小衛!");  
	return 0;  
}  
static const luaL_Reg reg[]=
{
	{"func",extFunc},
	 {NULL, NULL}
}; 
//模塊名字 dll名字
//被加載器加載
 extern "C" _declspec(dllexport) int luaopen_usher_luaex(lua_State *L)  
{  
	//lua 函數

	luaL_openlib(L, "usher", reg, 0);
	return 0;//沒有返回值
}
BOOL WINAPI DllMain(
	__in  HINSTANCE hinstDLL,
	__in  DWORD fdwReason,
	__in  LPVOID lpvReserved
	)
{

	return TRUE ;
}
//lua插件調用代碼如下
require("usher.luaex")  //加載當前package.cpath下的usher\luaex.dll 插件 並且 加載入口函數從而加載 lua擴展庫
usher.func()


便已生成的dll我們可以發現 導出了如下函數 luaopen_usher_luaex用給lua模塊進行加載

\

生成的擴展模塊dll如下

\

最終運行結果如下




好了到現在開始你也可以為Lua 寫 擴展庫了,下一張詳細分析Lua的 require 包含機制











  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved