第一步搭建lua的環境.
win10 lua環境搭建-CSDN博客
我使用的環境是win10+vs2015+lua54
先來個最簡單的lua調用C++函數,
無參數無返回值的
第一步:定義C++函數.
int CTest(lua_State* L) // 返回值是固定的int類型,返回0表示沒有返回參數,返回1表示有一個返回參數
{std::cout << "int CTest" << std::endl;return 0;
}
這個函數,除了函數名可以自己定義其他的都要按這個來定義.
返回值是固定的int類型,返回0表示沒有返回參數,返回1表示有一個返回參數.
第二步:注冊函數.
lua_register(lua,"CTest",CTest);?
第一個參數是lua的lua_State的指針,第二個是lua的注冊函數名字,這個名字是在lua代碼里使用的,第三個參數是函數指針就是剛才定義的C++函數.
#include <iostream>
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}int CTest(lua_State* L) // 返回值是固定的int類型,返回0表示沒有返回參數,返回1表示有一個返回參數
{std::cout << "int CTest" << std::endl;return 0;
}int main()
{lua_State *lua = luaL_newstate();luaopen_base(lua);luaopen_string(lua);lua_register(lua,"CTest",CTest); //第一個參數是lua狀態指針,第二個參數是函數名稱,第三個參數是lua函數指針,第二個參數和第三個參數可以用不同的名字,但第三個必須使用正確的函數指針luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");lua_pcall(lua, 0,0,0);getchar();return 0;
}
直接運行
這樣就是lua調用到了C++函數.當然這里lua調用C++ 函數是指在C++代碼中的調用.
lua傳遞參數,沒有返回值
只需要從lua的堆棧拿出一個參數即可.在此之前還需要再注冊一下.
lua_register(lua, "CTestToString", CTestToString);
const char* luaStr = lua_tostring(L,1);
?這樣得到的就是lua傳遞的參數.
int CTestToString(lua_State* L)
{const char* luaStr = lua_tostring(L,1);std::cout << luaStr << std::endl;return 0;
}
?
?傳第二個參數就再獲取一下第二個參數.
?
int num = lua_tointeger(L,2);
int CTestToString(lua_State* L)
{const char* luaStr = lua_tostring(L,1);std::cout << luaStr << std::endl;int num = lua_tointeger(L,2);std::cout << num << std::endl;return 0;
}
?
傳遞普通參數就這樣傳遞.
lua傳遞數組給C++函數
第一步注冊函數:
lua_register(lua, "CTestArr", CTestArr);
第二步:編寫接收函數
int CTestArr(lua_State* L)
{std::vector<std::string> vStr;std::cout << "int CTestArr" << std::endl;int arraySize = luaL_len(L, 1); //獲取表的大小for (int i = 1; i <= arraySize; ++i){lua_pushnumber(L,i); //往棧中壓入一個數字,表示從數組中取那個下標的值,lua都是從1開始的所以i從1開始lua_gettable(L, 1); //把上一行索引的位置出棧,再把i壓入 棧vStr.push_back(lua_tostring(L,-1));lua_pop(L,1);}for (auto& value : vStr){std::cout << value << std::endl;}return 0;
}
第三步:lua調用
.
lua傳遞表給C++函數
lua_next3(L,3)
- 先從棧頂彈出一個key
- 從棧指定位置的table里取下一對key-value,先將key入棧再將value入棧
- 如果第2步成功則返回非0值,否則返回0,并且不向棧中壓入任何值.
第一步注冊函數:
lua_register(lua, "CTestTable", CTestTable);
第二步:
int CTestTable(lua_State* L)
{std::cout << "int CTestTable" << std::endl;std::map<std::string, std::string> mStr;lua_pushnil(L);while (lua_next(L, 1) != 0){mStr[lua_tostring(L, -2)] = lua_tostring(L,-1);lua_pop(L,1);}for (auto& value : mStr){std::cout << value.first << " = " << value.second << std::endl;}return 0;
}
第三步lua調用:
?結果:
lua調用C++ 獲取表中的內容
lua_getfield(L,1,"name");std::cout << lua_tostring(L,-1) << std::endl;
Lua調用C++參數類型檢查
luaL_checktype(L,1,LUA_TBOOLEAN);if (lua_type(L, 1) != LUA_TBOOLEAN){luaL_argerror(L,1,"bad argument");}
第一行,一旦不匹配代碼就不會往下執行,
第二行的不匹配還會往下執行.
Lua調用C++ 返回值普通類型
第一步:注冊函數:
lua_register(lua, "TestRe", TestRe);
第二步寫函數:
int TestRe(lua_State* L)
{lua_pushstring(L,"return value");return 1;
}
一個返回參數就返回1,兩個就返回2
第三步lua代碼
結果:
lua返回表
第一步注冊函數:
lua_register(lua, "TestReTable", TestReTable);
第二步寫注冊函數
int TestReTable(lua_State* L)
{lua_newtable(L); // 創建一個表格,放在棧頂lua_pushstring(L,"name"); // 壓入keylua_pushstring(L,"ccname");//壓入valuelua_settable(L,-3); //彈出key value,并設置到表,表在棧頂了作為返回值lua_pushstring(L, "age"); // 壓入keylua_pushinteger(L, 21);//壓入valuelua_settable(L, -3); //彈出key value,并設置到表,表在棧頂了作為返回值return 1;
}
第三步:lua
結果:
C++全部代碼:
#include <iostream>
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include <vector>
#include <string>
#include <map>int CTest(lua_State* L) // 返回值是固定的int類型,返回0表示沒有返回參數,返回1表示有一個返回參數
{std::cout << "int CTest" << std::endl;return 0;
}int CTestToString(lua_State* L)
{const char* luaStr = lua_tostring(L,1);std::cout << luaStr << std::endl;int num = lua_tointeger(L,2);std::cout << num << std::endl;bool is = lua_toboolean(L, 3);std::cout << is << std::endl;return 0;
}int CTestArr(lua_State* L)
{std::vector<std::string> vStr;std::cout << "int CTestArr" << std::endl;int arraySize = luaL_len(L, 1); //獲取表的大小for (int i = 1; i <= arraySize; ++i){lua_pushnumber(L,i); //往棧中壓入一個數字,表示從數組中取那個下標的值,lua都是從1開始的所以i從1開始lua_gettable(L, 1); //把上一行索引的位置出棧,再把i壓入 棧vStr.push_back(lua_tostring(L,-1));lua_pop(L,1);}for (auto& value : vStr){std::cout << value << std::endl;}return 0;
}int CTestTable(lua_State* L)
{std::cout << "int CTestTable" << std::endl;/* 讀取全部的表的內容 */std::map<std::string, std::string> mStr;lua_pushnil(L);while (lua_next(L, 1) != 0){mStr[lua_tostring(L, -2)] = lua_tostring(L,-1);lua_pop(L,1);}for (auto& value : mStr){std::cout << value.first << " = " << value.second << std::endl;}/* 只取一個lua_getfield(L,1,"name");std::cout << lua_tostring(L,-1) << std::endl;*/return 0;
}int TestRe(lua_State* L)
{lua_pushstring(L,"return value");return 1;
}int TestReTable(lua_State* L)
{lua_newtable(L); // 創建一個表格,放在棧頂lua_pushstring(L,"name"); // 壓入keylua_pushstring(L,"ccname");//壓入valuelua_settable(L,-3); //彈出key value,并設置到表,表在棧頂了作為返回值lua_pushstring(L, "age"); // 壓入keylua_pushinteger(L, 21);//壓入valuelua_settable(L, -3); //彈出key value,并設置到表,表在棧頂了作為返回值return 1;
}int main()
{lua_State *lua = luaL_newstate();luaopen_base(lua);luaopen_string(lua);lua_register(lua,"CTest",CTest); //第一個參數是lua狀態指針,第二個參數是函數名稱,第三個參數是lua函數指針,第二個參數和第三個參數可以用不同的名字,但第三個必須使用正確的函數指針lua_register(lua, "CTestToString", CTestToString);lua_register(lua, "CTestArr", CTestArr);lua_register(lua, "CTestTable", CTestTable);lua_register(lua, "TestRe", TestRe);lua_register(lua, "TestReTable", TestReTable);luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");lua_pcall(lua, 0,0,0);getchar();return 0;
}
lua全部代碼:
CTest()CTestToString("lua string",123456,true)
local arr = {"A001","A002","A003"};
CTestArr(arr)
local tab = {name="xiaoming",age="22",id="007"};
CTestTable(tab)local re = TestRe()
print("re = " .. re)local retab = TestReTable()
print("name = " .. retab["name"])
print("name = " .. retab["age"])