最近在看lua,覺得很有趣,發現沒有最新版本的例子,所以自己就別人的博客里弄了源碼,然后改成最新版本的lua C API.
關于lua非常基礎的就不介紹了,咱們就從簡單的測試開始吧。
在此之前如果沒有搭好lua在win32下的環境,請看 https://www.jb51.net/article/61451.htm
1.C/C++執行lua腳本
我只是用改用了最新的lua的C API。不多說,直接上代碼
#include iostream>
#include stdlib.h>
#include stdio.h>
#include string.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
using namespace std;
int main()
{
lua_State *pLuaState = luaL_newstate();
/*載入lua基本庫*/
luaL_openlibs(pLuaState);
//luaopen_base(pLuaState);
//luaopen_io(pLuaState); //替換老版本的lua_iolibopen(pLuaState);
//luaopen_string(pLuaState); //替換老版本的lua_strlibopen(pLuaState);
//luaopen_math(pLuaState); //替換老版本的lua_mathlibopen(pLuaState);
//luaopen_debug(pLuaState); //替換老版本的lua_dblibopen(pLuaState);
/*運行腳本*/
luaL_dofile(pLuaState,"./script/hw.lua");
/*清除lua*/
lua_close(pLuaState);
/*暫停*/
cout"Press enter to exit…"endl;
getchar();
return 0;
}
hw.lua的源碼:
這個例子只是簡單的執行了一個lua腳本。
其中:lua_newstate是核心函數,要求提供內存分配函數,luaL_newstate是輔助庫函數,采用默認的內存分配函數。lua_open是5.0時代的產物,5.1是luaL_newstate的宏,5.2里面已經沒有了。
2.C/C++調用lua函數
話不多說,直接上代碼
#include iostream>
#include stdlib.h>
#include stdio.h>
#include string.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
using namespace std;
/************************************************************************/
//函數功能:調用lua函數
//函數參數:
// L lua虛擬機
// x
// y
//函數返回:
// sum
//核心函數 lua_call()
/*
調用一個函數。
要調用一個函數請遵循以下協議: 首先,要調用的函數應該被壓入堆棧; 接著,把需要傳遞給這個函數的參數按正序壓棧;
這是指第一個參數首先壓棧。 最后調用一下 lua_call; nargs 是你壓入堆棧的參數個數。 當函數調用完畢后,所有的參數以及函數本身都會出棧。
而函數的返回值這時則被壓入堆棧。 返回值的個數將被調整為 nresults 個, 除非 nresults 被設置成 LUA_MULTRET。
在這種情況下,所有的返回值都被壓入堆棧中。 Lua 會保證返回值都放入棧空間中。
函數返回值將按正序壓棧(第一個返回值首先壓棧), 因此在調用結束后,最后一個返回值將被放在棧頂。
被調用函數內發生的錯誤將(通過 longjmp)一直上拋。
*/
/************************************************************************/
int luaadd(lua_State *L, int x, int y)
{
int sum;
/*通過名字獲取Lua函數*/
lua_getglobal(L,"add");
/*向棧中壓入第一個參數*/
lua_pushnumber(L,x);
/*向棧中壓入第二個參數*/
lua_pushnumber(L,y);
/*調用函數*/
lua_call(L,2,1);
/*得到結果
把給定索引處的 Lua 值轉換為 lua_Integer 這樣一個有符號整數類型。
這個 Lua 值必須是一個數字或是一個可以轉換為數字的字符串,否則,lua_tointeger 返回 0 。*/
sum = (int)lua_tointeger(L,-1);
/*從堆棧中彈出 n 個元素*/
//n
lua_pop(L,1);
return sum;
}
int main()
{
int sum;
/*初始化lua虛擬機*/
lua_State *L = luaL_newstate();
/*載入lua基本庫*/
luaL_openlibs(L);
/*載入腳本*/
luaL_dofile(L,"./script/test.lua");
/*調用lua函數*/
sum = luaadd(L,10,15);
/*顯示結果*/
cout"The sum = "sumendl;
/*清除lua虛擬機*/
lua_close(L);
/*顯示結果并暫停*/
cout"Press enter to exit…"endl;
getchar();
return 0;
}
test.lua代碼為:
function add(x,y)
return x + y;
end
其中關于lua的堆棧問題,目前我還沒有了解,希望大家多多指教。
3.lua調用C/C++函數
代碼為:
#include iostream>
#include stdlib.h>
#include stdio.h>
#include string.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
using namespace std;
static int average(lua_State *L)
{
/*得到參數個數*/
int n = lua_gettop(L);
/*定義和*/
double sum = 0;
/*循環變量*/
int i;
/*循環取值求和*/
for (i = 1; i = n; i++)
{
sum += lua_tonumber(L,i);
//coutsumendl;
}
//cout"fffffff"endl;
/*壓入平均值*/
lua_pushnumber(L,sum/n);
/*壓入和*/
lua_pushnumber(L,sum);
/*返回返回值個數*/
return 2;
}
int main()
{
/*初始化Lua虛擬機*/
lua_State *L = luaL_newstate();
/*打開lua基本庫*/
luaL_openlibs(L);
/*注冊函數*/
lua_register(L,"average",average);
/*運行腳本*/
luaL_dofile(L,"./script/avg.lua");
/*清除lua虛擬機*/
lua_close(L);
/*打印暫停*/
cout"Press enter to exit…"endl;
getchar();
return 0;
}
avg.lua源碼為:
function main()
local avg,sum = average(2,2,2,2,2);
print("The avg is",avg);
print("The sum is", sum);
end
main();
您可能感興趣的文章:- Lua基礎教程之表(Table)學習筆記
- Lua基礎教程之賦值語句、表達式、流程控制、函數學習筆記
- 在Lua中使用模塊的基礎教程