爲Lua5.2.2編寫C模塊

本文的環境是win7和VS2010:

1.首先到官網下載lua5.2.2源碼包,並且在VS2010上新建空工程比如命名LuaCons,將源碼包中的頭文件和源文件都添加進去。

2.需要生成lua的動態鏈接庫,首先去掉源文件中的lua.c,並且在vs中的屬性->常規->配置類型,修改爲動態庫(.dll),並且在

屬性->C/C++->預處理器中,添加預定義LUA_COMPAT_ALL和LUA_BUILD_AS_DLL,當然這些預定義可以在luaconf.h中

開頭定義好,不過我不怎麼喜歡修改自帶文件的方式。

3.右鍵生成,於是在Debug中可以看到生成的LuaCons.dll和LuaCons.lib。

4.新建C模塊工程(怕麻煩就在同一個解決方案中即可)比如命名爲mylib。在C/C++->常規->附加包含目錄中填上指向解壓後的src路徑

比如相對路徑../xxxx/src或者絕對路徑D:/xxxx/src,在鏈接器->常規->附加庫目錄中填上直到剛纔生成的動態庫路徑,

相對或者絕對的都可以比如D:/xxxx/Debug。在鏈接器->輸入->附加依賴項中添加LuaCons.lib。

5.在模塊工程中新建mylib.h和mylib.cpp文件,填上:

mylib.h文件:

#ifndef _MYLIB_H 
#define _MYLIB_H

extern "C" 

#include "lua.h" 
#include "lualib.h" 
#include "lauxlib.h" 
};

extern "C" int __declspec(dllexport) luaopen_mylib(lua_State *L);

#endif //_MYLIB_H

由於使用C++編譯器,所以lua的三個頭文件需要以extern “C”擴起來。並且導出函數入口點必須是luaopen_xxx,

其中xxx就是要生成C模塊(dll)庫的名字。

mylib.cpp文件:

#include "mylib.h"

//說明:lua的交換棧,棧底部爲1,向棧頂遞增;也可認爲棧頂部爲-1,向棧底部遞減

//演示返回多個參數 
extern "C" static int l_mystr(lua_State *L) 

    lua_pushstring(L, "looyer");//返回的第一個參數, 字符串“looyer” 
    lua_pushnumber(L, 37);//返回的第二個參數,數字37

    //返回第三個參數table = {['ac'] = 17, [2] = "bn"} 
    lua_newtable(L);//在棧頂創建一個table

    //方法一,設置table的鍵和值 
    lua_pushstring(L, "ac"); 
    lua_pushnumber(L, 17); 
    lua_settable(L, -3);//在table中設置鍵值對['ac'] = 17, 設置後,自動pop掉棧頂的兩個元素

    //方法二,設置table的鍵和值 
    lua_pushstring(L, "bn"); 
    lua_setfield(L, -2, "2");//將棧頂元素設置爲鍵“2”的值,並且賦個索引爲-2的棧中table

    return 3;//返回參數的個數 
}

//演示輸入多個參數,檢查輸入一個數字,一個字符串,一個table 
extern "C" static int l_myadd(lua_State *L) 

    int a = luaL_checknumber(L, 1); 
    const char *p = luaL_checkstring(L, 2); 
    lua_getfield(L, 3, "yt");//將第三個參數table的“yt”鍵的值壓入棧 
    int b = luaL_checknumber(L, -1);//取出該“yt”鍵的值 
    lua_pushnumber(L, a + b); 
    return 1;//返回一個參數 
}

static const struct luaL_Reg mylib[] = 

    {"mystr", l_mystr}, 
    {"inadd", l_myadd}, 
    {NULL, NULL} 
};

int luaopen_mylib(lua_State *L) 

    luaL_newlib(L, mylib); 
    return 1; 
}

6.點擊生成,即可看到Debug庫中生成了mylib.dll和mylib.lib,我們只需要mylib.dll即可。

7.在lua中調用我們寫好的dll模塊,首先在LuaCons工程中添加剛剛移除的lua.c文件,然後移除luac.c文件,記住不要去掉剛纔定義的兩個宏,

否則待會在lua中加載會失敗,特別是去掉LUA_BUILD_AS_DLL會在loadlib.c中的ll_load函數中的WIN32函數LoadLibraryExA中發生加載錯誤,

其錯誤待會爲193-ERROR_BAD_EXE_FORMAT,不知爲什麼,留着以後調試吧。

8.將LuaCons工程的類型從dll改回生成應用程序的形式。生成即可。

9.嘗試加載剛剛寫的C模塊,假如mylib.dll和LuaCons.exe在同一個文件夾下,運行如下:


假如mylib.dll和LuaCons.exe不在同一個文件夾下,只需要修改package.cpath即可,比如mylib.dll在D:\Lib中只需要在require之前添加

package.cpath = package.cpath .. “;D:\\Lib\\?.dll”即可。

後記,關於Lua的更多的知識,我還需要多多學習,開始時也是錯誤多多,後面跟着程序調試就好了。Play Happy!~


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章