背景
學了一段時間lua,由於luacom不支援gbk,所以想做一個gbk轉換成utf-8的模組。但是不會寫模組怎麼辦?學!
目標
建立一個calc模組,輸出兩個函數 sum和average,最後在lua程式想這樣用:
require "calc"a = 5b = 10print(calc.sum(a,b))print(calc.average(a,b))
學習過程簡述
- 讀Programming in Lua有關C API一節
- 讀Lua Reference Manual ->
The Application Program Interface 一節
- 下載lua5.1.4原始碼,查看標準庫 *lib.c 檔案是怎麼寫的
- 查看require函數原始碼
學習總結
require("xxx") 函數在調用C模組時,會在cpath中尋找 xxx.dll檔案,若找到則調用 luaopen_xxx函數, luaopen_xxx 函數也必須 luc_CFunction 類型的。
使用者可以在luaopen_xxx函數中用capi做任何事情,但一般是用luaL_register註冊一組函數到一個table中,並返回這個table
配置lua編譯環境
- 安裝luaforwindows
- 開啟vs2008,工具->選項->項目和解決方案->VC++目錄
- 右上方選擇 包含檔案,添加luaforwindows安裝目錄中的include目錄,比如 C:\Program Files\Lua\5.1\include
- 右上方選擇 庫檔案,添加luaforwindows安裝目錄中lib目錄,比如 C:\Program Files\Lua\5.1\lib
產生calc模組
建立工程
開啟vs2008,建立 -> 項目 -> Visual C++ -> Win32 -> Win32項目 -> 輸入項目名 calc
應用程式類型:DLL
附加選項:空項目
添加庫引用
右上方選擇 所有配置
配置屬性 -> 連結器 -> 附加依賴項 -> 輸入 lua51.lib
添加源檔案
添加一個新的檔案 calc.c (注意是 .c 不是.cpp ),原始碼如下:
//包含3個lua標頭檔//如果本檔案是cpp檔案,則不要包含下面3個檔案,而包含 lua.hpp 檔案#include <lua.h>#include <lualib.h>#include <lauxlib.h>static int sum(lua_State *L) {lua_Number a = luaL_checknumber(L, 1); //檢查第1個參數是數字,如果是則返回這個數字lua_Number b = luaL_checknumber(L, 2); //檢查第2個參數是數字,如果是則返回這個數字lua_pushnumber(L, a+b); //傳回值return 1; //函數傳回值個數}static int average(lua_State *L) {lua_Number a = luaL_checknumber(L, 1); //檢查第1個參數是數字,如果是則返回這個數字lua_Number b = luaL_checknumber(L, 2); //檢查第2個參數是數字,如果是則返回這個數字lua_pushnumber(L, (a+b)/2); //傳回值return 1; //函數傳回值個數}static luaL_Reg module_functions[] = {{"sum", sum}, //函數名,函數{"average", average},{NULL, NULL} //結尾};//注意用__declspec(dllexport)輸出函數//如果本檔案是 cpp 檔案,則必須加extern "C"__declspec(dllexport) int luaopen_calc(lua_State *L) {luaL_register(L, "calc", module_functions); //建立一個全域的calc table,所有函數都會按照指定名稱註冊成calc table的成員函數return 1; //luaopen_calc也是一個luc_CFunction,返回傳回值的個數,傳回值是由luaL_register壓入棧的}
產生並測試
產生release版的calc.dll,然後在calc.dll所在目錄,建立一個 test.lua檔案,把本文目標(上面)中的lua來源程式拷進去,運行!結果正確!!
如果需要長期使用calc.dll,則可以將它拷貝到luaforwindows的clibs檔案夾中,比如C:\Program Files\Lua\5.1\clibs
到此為止,我們已經掌握了用VS寫lua C模組的基本方法了,下一篇文章,講講自己讓luacom能夠開啟中文的word檔案。