? ? ? ? Lua 是一門輕量級、嵌入式的腳本語言,常常與 C/C++ 結合使用。通過嵌入 Lua,可以讓應用程序獲得靈活的配置、腳本化邏輯和可擴展性。
? ? ? ? ?本文將介紹如何在 C/C++ 調用 Lua 函數,以及如何讓 Lua 調用 C/C++ 函數。最后給出一個 完整的示例工程,可以直接編譯運行。
一、C 調用 Lua
Lua 腳本(script.lua
):
-- 定義一個 Lua 函數
function add(a, b)return a + b
end
C++ 代碼調用:
lua_getglobal(L, "add"); // 獲取 Lua 中的函數
lua_pushnumber(L, 10); // 壓入參數
lua_pushnumber(L, 20);if (lua_pcall(L, 2, 1, 0) != 0) {std::cerr << "Error: " << lua_tostring(L, -1) << std::endl;
}double result = lua_tonumber(L, -1); // 獲取返回值
lua_pop(L, 1); // 彈出棧頂
運行后會輸出 30
。
二、Lua 調用 C/C++
Lua 可以調用在 C/C++ 里注冊的函數。
C++ 代碼:
int cpp_multiply(lua_State* L) {int a = luaL_checkinteger(L, 1);int b = luaL_checkinteger(L, 2);lua_pushinteger(L, a * b);return 1; // 返回值數量
}
注冊函數:
lua_register(L, "cpp_multiply", cpp_multiply);
Lua 調用:
print("cpp_multiply result:", cpp_multiply(6, 7))
運行后會輸出 42
。
三、完整示例工程
目錄結構
demo-lua/
├── CMakeLists.txt
├── main.cpp
└── script.lua
1. CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(demo-lua CXX)set(CMAKE_CXX_STANDARD 11)# 查找 Lua
find_package(PkgConfig REQUIRED)
pkg_search_module(LUA REQUIRED lua5.3)include_directories(${LUA_INCLUDE_DIRS})
link_directories(${LUA_LIBRARY_DIRS})add_executable(demo main.cpp)
target_link_libraries(demo ${LUA_LIBRARIES})
2. script.lua
-- Lua 腳本文件-- 定義函數
function add(a, b)return a + b
end-- 調用 C++ 注冊的函數
function test_cpp_func()local res = cpp_multiply(6, 7)print("cpp_multiply result from Lua:", res)
end
3. main.cpp
#include <iostream>
#include <lua.hpp>// C++ 函數:在 Lua 中注冊為 cpp_multiply
int cpp_multiply(lua_State* L) {int a = luaL_checkinteger(L, 1);int b = luaL_checkinteger(L, 2);lua_pushinteger(L, a * b);return 1;
}int main() {lua_State* L = luaL_newstate(); // 創建 Lua 虛擬機luaL_openlibs(L); // 打開標準庫// 注冊 C++ 函數到 Lualua_register(L, "cpp_multiply", cpp_multiply);// 加載 Lua 腳本if (luaL_dofile(L, "script.lua")) {std::cerr << "Failed to load script.lua: "<< lua_tostring(L, -1) << std::endl;lua_close(L);return 1;}// 調用 Lua 的 add() 函數lua_getglobal(L, "add");lua_pushnumber(L, 10);lua_pushnumber(L, 20);if (lua_pcall(L, 2, 1, 0) != 0) {std::cerr << "Error running add(): "<< lua_tostring(L, -1) << std::endl;lua_close(L);return 1;}double result = lua_tonumber(L, -1);lua_pop(L, 1);std::cout << "Result from Lua add(): " << result << std::endl;// 調用 Lua 的 test_cpp_func()lua_getglobal(L, "test_cpp_func");if (lua_pcall(L, 0, 0, 0) != 0) {std::cerr << "Error running test_cpp_func(): "<< lua_tostring(L, -1) << std::endl;}lua_close(L);return 0;
}
四、構建與運行
# 編譯
mkdir build && cd build
cmake ..
make# 運行
./demo