Lua 是一门轻量级、嵌入式的脚本语言,常常与 C/C++ 结合使用。通过嵌入 Lua,可以让应用程序获得灵活的配置、脚本化逻辑和可扩展性。
本文将介绍如何在 C/C++ 调用 Lua 函数 ,以及如何让 Lua 调用 C/C++ 函数 。最后给出一个 完整的示例工程,可以直接编译运行。
一、C 调用 Lua
Lua 脚本(script.lua
):
Lua
-- 定义一个 Lua 函数
function add(a, b)
return a + b
end
C++ 代码调用:
cpp
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++ 代码:
cpp
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; // 返回值数量
}
注册函数:
cpp
lua_register(L, "cpp_multiply", cpp_multiply);
Lua 调用:
Lua
print("cpp_multiply result:", cpp_multiply(6, 7))
运行后会输出 42
。
三、完整示例工程
目录结构
bash
demo-lua/
├── CMakeLists.txt
├── main.cpp
└── script.lua
1. CMakeLists.txt
bash
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
-- 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
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++ 函数到 Lua
lua_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;
}
四、构建与运行
bash
# 编译
mkdir build && cd build
cmake ..
make
# 运行
./demo
五、运行效果