简介
主要搭建了一个最最简单的lua与c++交互的demo。可以从demo中学习到,如何引入lua头文件、库目录。如何实现c++调用lua代码,以及lua调用c++代码。
目录结构预览
通常在创建项目时,需要对项目有个大概设想,东西怎么存放是个很基本的事情。虽然项目很简单,但还是象征性的把源代码与第三方库分开了。3rd
目录主要用于放置各种第三方库,这里面放了luajit库目录。lua
目录主要用于放置lua的各类源代码。source
目录主要用于放置C++源代码。
├─3rd
│ └─luajit
│ ├─doc
│ │ └─img
│ ├─dynasm
│ ├─etc
│ └─src
│ ├─host
│ └─jit
├─lua
└─source
编译luajit源码
- 在
3rd
目录下,用git clone https://luajit.org/git/luajit.git
命令把luajit源码目录拉下来。 - 进入luajit源码目录,使用里面预置好的脚本文件进行编译。注意windows下需要在
Visual Studio Command Prompt
环境下编译。
准备Visual Sudio项目
项目流程主要如下。
- 首先创建一个空的Visual Sudio项目目录。
- 其次按照前述目录结构进行构建。
- 配置头文件。
- 在 Visual Studio 右侧的 “解决方案资源管理器” 中,右键点击你的项目名称(注意是项目,不是解决方案),然后选择 “属性”。
- 在属性窗口的顶部,确保 “配置” 设置为 “所有配置 (All Configurations)”,“平台” 设置为 “所有平台 (All Platforms)”。这样你的设置就会对 Debug 和 Release 模式同时生效,避免重复设置。
- 在左侧导航栏,展开 “配置属性” -> “C/C++” -> “常规 (General)”。
- 在右侧的选项中,找到 “附加包含目录 (Additional Include Directories)”。
- 点击“附加包含目录”右边的下拉箭头,选择 “<编辑…>”。
- 在弹出的新窗口中,点击第一行的图标(“新建行”)。
- 将lua头文件目录
$(ProjectDir)\3rd\luajit\src;
路径加入。
- 配置库文件。
- 还是在项目属性页面。
- 在左侧导航栏,展开 “配置属性” -> “链接器 (Linker)” -> “常规 (General)”。
- 在右侧找到 “附加库目录 (Additional Library Directories)”。
- 同样地,点击 “<编辑…>” 并添加你的
.lib
文件所在的目录。 - 添加
$(ProjectDir)\3rd\luajit\src;
路径。luajit编译后.lib
文件和源代码文件均在该目录下。 - 除了链接外还需要指定用到的lib文件。
- 在左侧导航栏,选择 “链接器 (Linker)” -> “输入 (Input)”。
- 在右侧找到 “附加依赖项 (Additional Dependencies)”。
- 点击 “<编辑…>”,在弹出的窗口中,输入用到的
lua51.lib
。
编写main文件
主要是编写main.cpp
和main.lua
。分别放在source
和lua
目录下。
// main.cpp
#include <iostream>
// 关键头文件
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
// 这是一个符合 lua_CFunction 规范的 C++ 函数
static int cpp_multiply(lua_State* L) {
// 1. 从堆栈中获取参数
// luaL_checknumber 会检查参数类型,如果不对会报错
double a = luaL_checknumber(L, 1); // 第一个参数在索引 1
double b = luaL_checknumber(L, 2); // 第二个参数在索引 2
// 2. 执行 C++ 逻辑
double result = a * b;
// 3. 将返回值压入堆栈
lua_pushnumber(L, result);
// 4. 返回 1,表示有 1 个返回值
return 1;
}
int main() {
// 1. 创建一个 Lua 状态机(Lua 虚拟机)
lua_State* L = luaL_newstate();
if (L == nullptr) {
std::cerr << "Error: Failed to create Lua state." << std::endl;
return 1;
}
// 2. 加载 Lua 标准库 (例如 print, ipairs 等)
// 这对于编写 Lua 脚本非常重要
luaL_openlibs(L);
std::cout << "Lua state created successfully." << std::endl;
// 注册c++函数供lua调用
lua_pushcfunction(L, cpp_multiply);
lua_setglobal(L, "multiply");
// c++中调用lua文件
int result = luaL_dofile(L, "lua/main.lua");
if (result != LUA_OK) {
// 如果脚本执行出错,错误信息会被压入栈顶
const char* error_message = lua_tostring(L, -1);
std::cerr << "Error executing Lua script: " << error_message << std::endl;
lua_close(L);
return 1;
}
// 3. 关闭和释放 Lua 状态机
lua_close(L);
std::cout << "Lua state closed." << std::endl;
return 0;
}
-- main.lua
print("Hello from Lua script!")
print(multiply(5,6))
编译运行
最后直接编译运行main.cpp即可。
在VS中推荐使用Ctrl+F5运行,这样就会在程序执行结束后暂停在命令行中而不会直接关闭命令行。
Lua state created successfully.
Hello from Lua script!
30
Lua state closed.
L:\LuaCpp\x64\Debug\LuaCpp.exe (进程 11200)已退出,代码为 0。
按任意键关闭此窗口. . .